ZQuest Classic Coverage Report


Directory: src/
File: src/zc/maps.cpp
Date: 2025-08-22 09:44:27
Exec Total Coverage
Lines: 4079 5081 80.3%
Functions: 291 329 88.4%
Branches: 3121 5099 61.2%

Line Branch Exec Source
1 #include "base/combo.h"
2 #include "base/handles.h"
3 #include "base/util.h"
4 #include "base/zdefs.h"
5 #include "base/general.h"
6 #include <cstring>
7 #include <assert.h>
8 #include <math.h>
9 #include <vector>
10 #include <deque>
11 #include <string>
12 #include <set>
13 #include <array>
14 #include <sstream>
15 using std::set;
16
17 #include "base/qrs.h"
18 #include "base/dmap.h"
19 #include "base/mapscr.h"
20 #include "base/misctypes.h"
21 #include "base/initdata.h"
22 #include "zc/maps.h"
23 #include "zc/zelda.h"
24 #include "zc/zc_ffc.h"
25 #include "tiles.h"
26 #include "sprite.h"
27 #include "gui/jwin.h"
28 #include "base/zsys.h"
29 #include "subscr.h"
30 #include "zc/zc_subscr.h"
31 #include "zc/hero.h"
32 #include "zc/guys.h"
33 #include "zc/ffscript.h"
34 #include "drawing.h"
35 #include "zc/combos.h"
36 #include "zc/replay.h"
37 #include "slopes.h"
38 #include "particles.h"
39 #include <fmt/format.h>
40 #include "zc/render.h"
41 #include "iter.h"
42 #include <ranges>
43
44 // All the temporary screens (and their layers) for the currently loaded map.
45 static mapscr* temporary_screens[136*7];
46 // Set by load_region.
47 static bool screen_in_current_region[136];
48 412 static rpos_handle_t current_region_rpos_handles[136*7];
49 static bool current_region_rpos_handles_dirty;
50 static int current_region_screen_count;
51 static std::pair<const rpos_handle_t*, int> current_region_rpos_handles_scr[136];
52
53 viewport_t viewport;
54 static int viewport_sprite_uid;
55 ViewportMode viewport_mode;
56 int world_w, world_h;
57 int region_scr_dx, region_scr_dy;
58 int region_scr_count;
59 rpos_t region_max_rpos;
60 int region_num_rpos;
61 region_t cur_region, scrolling_region;
62
63 412 maze_state_t maze_state;
64 int scrolling_maze_last_solved_screen;
65
66 575 void maps_init_game_vars()
67 {
68 575 viewport = {};
69 575 viewport_mode = ViewportMode::CenterAndBound;
70 575 viewport_sprite_uid = 1;
71 575 currscr_for_passive_subscr = -1;
72 575 }
73
74 static region_ids_t current_region_ids;
75
76 14616166 static bool is_a_region(int map, int scr)
77 {
78 14616166 return get_region_id(map, scr) != 0;
79 }
80
81 2232 static bool is_same_region_id(int region_origin_scr, int map, int scr)
82 {
83
2/2
✓ Branch 0 taken 772 times.
✓ Branch 1 taken 1460 times.
2232 if (!is_a_region(map, scr)) return false;
84 1460 int region_id = get_region_id(map, region_origin_scr);
85
1/2
✓ Branch 0 taken 1460 times.
✗ Branch 1 not taken.
1460 return region_id && region_id == get_region_id(map, scr);
86 2232 }
87
88 137745940 bool is_in_current_region(int map, int screen)
89 {
90
5/6
✓ Branch 0 taken 137744367 times.
✓ Branch 1 taken 1573 times.
✓ Branch 2 taken 137744367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12213 times.
✓ Branch 5 taken 137732154 times.
137745940 return map == cur_map && screen >= 0 && screen < 128 && screen_in_current_region[screen];
91 }
92
93 69622303 bool is_in_current_region(int screen)
94 {
95
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 69622302 times.
69622303 return screen < 128 && screen_in_current_region[screen];
96 }
97
98 28995045 bool is_in_current_region(mapscr* scr)
99 {
100
4/4
✓ Branch 0 taken 28980024 times.
✓ Branch 1 taken 15021 times.
✓ Branch 2 taken 462663 times.
✓ Branch 3 taken 28517361 times.
28995045 return scr->map == cur_map && scr->screen < 128 && screen_in_current_region[scr->screen];
101 }
102
103 bool is_in_scrolling_region(int screen)
104 {
105 if (!screenscrolling) return false;
106
107 int x = screen % 16;
108 int y = screen / 16;
109 return
110 scrolling_region.origin_screen_x >= x && scrolling_region.origin_screen_x < x + scrolling_region.screen_width &&
111 scrolling_region.origin_screen_y >= y && scrolling_region.origin_screen_y < y + scrolling_region.screen_height;
112 }
113
114 9015230880 bool is_in_scrolling_region()
115 {
116 9015230880 return cur_region.screen_count > 1;
117 }
118
119 76829448 bool is_extended_height_mode()
120 {
121
2/2
✓ Branch 0 taken 76579314 times.
✓ Branch 1 taken 250134 times.
76829448 return cur_region.screen_height > 1 && (DMaps[cur_dmap].flags & dmfEXTENDEDVIEWPORT);
122 }
123
124 // Returns 0 if this is not a region.
125 15658208 int get_region_id(int map, int screen)
126 {
127
2/2
✓ Branch 0 taken 401435 times.
✓ Branch 1 taken 15256773 times.
15658208 if (screen >= 128) return 0;
128
2/2
✓ Branch 0 taken 15255673 times.
✓ Branch 1 taken 1100 times.
15256773 if (map == cur_region.map) return current_region_ids[screen];
129
130 1100 return Regions[map].get_region_id(screen);
131 15658208 }
132
133 982758 int get_current_region_id()
134 {
135 982758 return get_region_id(cur_map, cur_screen);
136 }
137
138 64215 void calculate_region(int map, int screen, region_t& region, int& region_scr_dx, int& region_scr_dy)
139 {
140 64215 region.map = map;
141
142
3/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 63941 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 274 times.
64215 if (!(is_a_region(map, screen)) || screen >= 0x80)
143 {
144 63941 region.region_id = 0;
145 63941 region.origin_screen = screen;
146 63941 region.origin_screen_x = screen % 16;
147 63941 region.origin_screen_y = screen / 16;
148 63941 region.screen_width = 1;
149 63941 region.screen_height = 1;
150 63941 region.screen_count = 1;
151 63941 region.width = 256;
152 63941 region.height = 176;
153 63941 region_scr_dx = 0;
154 63941 region_scr_dy = 0;
155 63941 return;
156 }
157
158 274 int input_scr_x = screen % 16;
159 274 int input_scr_y = screen / 16;
160
161 // For the given screen, find the top-left corner of its region.
162 274 int origin_scr_x = input_scr_x;
163 274 int origin_scr_y = input_scr_y;
164 274 int origin_scr = screen;
165
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 372 times.
434 while (origin_scr_x > 0)
166 {
167
2/2
✓ Branch 0 taken 212 times.
✓ Branch 1 taken 160 times.
372 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x - 1, origin_scr_y))) break;
168 160 origin_scr_x--;
169 }
170
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 414 times.
508 while (origin_scr_y > 0)
171 {
172
2/2
✓ Branch 0 taken 180 times.
✓ Branch 1 taken 234 times.
414 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, origin_scr_y - 1))) break;
173 234 origin_scr_y--;
174 }
175 274 origin_scr = map_scr_xy_to_index(origin_scr_x, origin_scr_y);
176
177 // Now find the bottom-right corner.
178 274 int region_scr_right = origin_scr_x;
179
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 614 times.
642 while (region_scr_right < 15)
180 {
181
2/2
✓ Branch 0 taken 246 times.
✓ Branch 1 taken 368 times.
614 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(region_scr_right + 1, origin_scr_y))) break;
182 368 region_scr_right++;
183 }
184 274 int region_scr_bottom = origin_scr_y;
185
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 832 times.
856 while (region_scr_bottom < 7)
186 {
187
2/2
✓ Branch 0 taken 250 times.
✓ Branch 1 taken 582 times.
832 if (!is_same_region_id(origin_scr, map, map_scr_xy_to_index(origin_scr_x, region_scr_bottom + 1))) break;
188 582 region_scr_bottom++;
189 }
190
191 274 region.region_id = get_region_id(map, origin_scr);
192 274 region.origin_screen = origin_scr;
193 274 region.origin_screen_x = origin_scr_x;
194 274 region.origin_screen_y = origin_scr_y;
195 274 region.screen_width = region_scr_right - origin_scr_x + 1;
196 274 region.screen_height = region_scr_bottom - origin_scr_y + 1;
197 274 region.screen_count = region.screen_width * region.screen_height;
198 274 region.width = 256 * region.screen_width;
199 274 region.height = 176 * region.screen_height;
200 274 region_scr_dx = input_scr_x - origin_scr_x;
201 274 region_scr_dy = input_scr_y - origin_scr_y;
202
203 DCHECK_RANGE_INCLUSIVE(region.screen_width, 0, 16);
204 DCHECK_RANGE_INCLUSIVE(region.screen_height, 0, 8);
205 64215 }
206
207 35854 void load_region(int dmap, int screen)
208 {
209 35854 clear_temporary_screens();
210
211 35854 int map = DMaps[dmap].map;
212 35854 current_region_ids = Regions[map].get_all_region_ids();
213
214 35854 calculate_region(map, screen, cur_region, region_scr_dx, region_scr_dy);
215 35854 cur_screen = cur_region.origin_screen;
216 35854 world_w = cur_region.width;
217 35854 world_h = cur_region.height;
218 35854 region_scr_count = cur_region.screen_count;
219 35854 region_max_rpos = (rpos_t)(cur_region.screen_count*176 - 1);
220 35854 region_num_rpos = cur_region.screen_count*176;
221 35854 scrolling_maze_last_solved_screen = 0;
222
223 35854 memset(screen_in_current_region, false, sizeof(screen_in_current_region));
224
2/2
✓ Branch 0 taken 36088 times.
✓ Branch 1 taken 35854 times.
71942 for (int x = 0; x < cur_region.screen_width; x++)
225 {
226
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36088 times.
73186 for (int y = 0; y < cur_region.screen_height; y++)
227 {
228 37098 int screen = cur_screen + x + y*16;
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen < 136)
230 {
231 37098 screen_in_current_region[screen] = true;
232 37098 }
233 37098 }
234 36088 }
235
236 35854 mark_current_region_handles_dirty();
237 35854 }
238
239 35854 static void prepare_current_region_handles()
240 {
241 35854 current_region_rpos_handles_dirty = false;
242 35854 current_region_screen_count = 0;
243
2/2
✓ Branch 0 taken 36202 times.
✓ Branch 1 taken 35854 times.
72056 for (int y = 0; y < cur_region.screen_height; y++)
244 {
245
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 36202 times.
73300 for (int x = 0; x < cur_region.screen_width; x++)
246 {
247 37098 int screen = cur_screen + x + y*16;
248 37098 int index_start = current_region_screen_count;
249
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 259686 times.
296784 for (int layer = 0; layer <= 6; layer++)
250 {
251 259686 mapscr* scr = get_scr_layer(screen, layer);
252
2/2
✓ Branch 0 taken 84550 times.
✓ Branch 1 taken 175136 times.
259686 if (!scr->is_valid())
253 {
254
1/2
✓ Branch 0 taken 175136 times.
✗ Branch 1 not taken.
175136 if (layer == 0) break;
255 175136 continue;
256 }
257
258 84550 rpos_t base_rpos = POS_TO_RPOS(0, get_region_relative_dx(screen), get_region_relative_dy(screen));
259 84550 current_region_rpos_handles[current_region_screen_count] = {scr, screen, layer, base_rpos, 0};
260 84550 current_region_screen_count += 1;
261 84550 }
262
263 37098 int num_handles_for_scr = current_region_screen_count - index_start;
264 37098 current_region_rpos_handles_scr[screen] = {&current_region_rpos_handles[index_start], num_handles_for_scr};
265 37098 }
266 36202 }
267 35854 }
268
269 1782348261 std::tuple<const rpos_handle_t*, int> get_current_region_handles()
270 {
271 DCHECK(!current_region_rpos_handles_dirty);
272 1782348261 return {current_region_rpos_handles, current_region_screen_count};
273 }
274
275 11056526 std::tuple<const rpos_handle_t*, int> get_current_region_handles(mapscr* scr)
276 {
277 DCHECK(!current_region_rpos_handles_dirty);
278
2/4
✓ Branch 0 taken 11056526 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11056526 times.
11056526 if (scr == special_warp_return_scr || current_region_rpos_handles_dirty)
279 return {nullptr, 0};
280
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11056526 times.
11056526 if (cur_screen >= 0x80)
282 {
283 DCHECK(scr == origin_scr);
284 return {nullptr, 0};
285 }
286
287 DCHECK(is_in_current_region(scr));
288 11056526 return current_region_rpos_handles_scr[scr->screen];
289 11056526 }
290
291 35854 void mark_current_region_handles_dirty()
292 {
293 35854 current_region_rpos_handles_dirty = true;
294 35854 }
295
296 64941 void delete_temporary_screens(mapscr** screens)
297 {
298
2/2
✓ Branch 0 taken 61823832 times.
✓ Branch 1 taken 64941 times.
61888773 for (int i = 0; i < 136*7; i++)
299 {
300
2/2
✓ Branch 0 taken 255689 times.
✓ Branch 1 taken 61568143 times.
61823832 if (!screens[i])
301 61568143 continue;
302
303 255689 mapscr* scr = screens[i];
304 255689 int num_ffcs = scr->numFFC();
305
2/2
✓ Branch 0 taken 7619480 times.
✓ Branch 1 taken 255689 times.
7875169 for (int i = 0; i < num_ffcs; i++)
306 {
307 7619480 sprite* ffc = &scr->ffcs[i];
308
2/2
✓ Branch 0 taken 7617623 times.
✓ Branch 1 taken 1857 times.
7619480 if (ffc->uid)
309 1857 FFCore.release_sprite_owned_objects(ffc->uid);
310 7619480 }
311
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 255689 times.
255689 delete scr;
312 255689 screens[i] = NULL;
313 255689 }
314 64941 }
315
316 36991 void clear_temporary_screens()
317 {
318 36991 delete_temporary_screens(temporary_screens);
319 36991 origin_scr = nullptr;
320 36991 hero_scr = nullptr;
321 36991 }
322
323 27954 std::vector<mapscr*> take_temporary_scrs()
324 {
325
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 std::vector<mapscr*> screens(temporary_screens, temporary_screens + 136*7);
326
2/2
✓ Branch 0 taken 27954 times.
✓ Branch 1 taken 26612208 times.
26640162 for (int i = 0; i < 136*7; i++)
327 26612208 temporary_screens[i] = nullptr;
328
329 27954 return screens;
330
1/2
✓ Branch 0 taken 27954 times.
✗ Branch 1 not taken.
27954 }
331
332 14550079 void calculate_viewport(viewport_t& viewport, int dmap, int screen, int world_w, int world_h, int x, int y)
333 {
334 // TODO: In future, maybe add x/y centering offsets to zscript (Viewport->TargetXOffset/Viewport->TargetYOffset).
335
336
2/2
✓ Branch 0 taken 14503497 times.
✓ Branch 1 taken 46582 times.
14550079 bool extended_height_mode = (DMaps[dmap].flags & dmfEXTENDEDVIEWPORT) && world_h > 176;
337 14550079 viewport.w = 256;
338 14550079 viewport.h = 176 + (extended_height_mode ? 56 : 0);
339
340
2/2
✓ Branch 0 taken 360 times.
✓ Branch 1 taken 14549719 times.
14550079 if (viewport_mode == ViewportMode::Script)
341 360 return;
342
343
2/2
✓ Branch 0 taken 46162 times.
✓ Branch 1 taken 14503557 times.
14549719 if (!is_a_region(DMaps[dmap].map, screen))
344 {
345 14503557 viewport.x = 0;
346 14503557 viewport.y = 0;
347 14503557 }
348
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46162 times.
46162 else if (viewport_mode == ViewportMode::CenterAndBound)
349 {
350 // Clamp the viewport to the edges of the region.
351
6/6
✓ Branch 0 taken 8568 times.
✓ Branch 1 taken 37594 times.
✓ Branch 2 taken 6788 times.
✓ Branch 3 taken 39374 times.
✓ Branch 4 taken 8568 times.
✓ Branch 5 taken 30806 times.
46162 viewport.x = CLAMP(0, world_w - viewport.w, x - viewport.w/2);
352
6/6
✓ Branch 0 taken 11856 times.
✓ Branch 1 taken 34306 times.
✓ Branch 2 taken 5650 times.
✓ Branch 3 taken 40512 times.
✓ Branch 4 taken 11856 times.
✓ Branch 5 taken 28656 times.
46162 viewport.y = CLAMP(0, world_h - viewport.h, y - viewport.h/2);
353 46162 }
354 else if (viewport_mode == ViewportMode::Center)
355 {
356 viewport.x = x - viewport.w/2;
357 viewport.y = y - viewport.h/2;
358 }
359 14550079 }
360
361 14549568 sprite* get_viewport_sprite()
362 {
363 14549568 sprite* spr = sprite::getByUID(viewport_sprite_uid);
364
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 14549562 times.
14549568 if (!spr)
365 {
366 6 viewport_sprite_uid = 1; // Hero uid.
367 6 spr = &Hero;
368 6 }
369
370 14549568 return spr;
371 }
372
373 6 void set_viewport_sprite(sprite* spr)
374 {
375 6 viewport_sprite_uid = spr->uid;
376 6 }
377
378 14521614 void update_viewport()
379 {
380 14521614 sprite* spr = get_viewport_sprite();
381 14521614 int x = spr->x + spr->txsz*16/2;
382 14521614 int y = spr->y + spr->tysz*16/2;
383 14521614 calculate_viewport(viewport, cur_dmap, cur_screen, world_w, world_h, x, y);
384 14521614 }
385
386 14309416 void update_heroscr()
387 {
388 void playLevelMusic();
389
390 14309416 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
391 14309416 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
392 14309416 int dx = x / 256;
393 14309416 int dy = y / 176;
394 14309416 int new_screen = cur_screen + dx + dy * 16;
395
2/2
✓ Branch 0 taken 14301654 times.
✓ Branch 1 taken 7762 times.
14309416 if (maze_state.active == 1)
396 7762 new_screen = maze_state.scr->screen;
397
7/12
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 14309200 times.
✓ Branch 2 taken 216 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 216 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 216 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 216 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 216 times.
14309416 if (hero_screen != new_screen && dx >= 0 && dy >= 0 && dx < 16 && dy < 8 && is_in_current_region(new_screen))
398 {
399 216 region_scr_dx = dx;
400 216 region_scr_dy = dy;
401 216 hero_screen = new_screen;
402 216 prev_hero_scr = hero_scr;
403 216 hero_scr = get_scr(hero_screen);
404 216 Hero.screen_spawned = hero_screen;
405 216 playLevelMusic();
406 216 }
407
1/2
✓ Branch 0 taken 14309416 times.
✗ Branch 1 not taken.
14309416 if (game->get_regionmapping() == REGION_MAPPING_PHYSICAL)
408 mark_visited(new_screen); // Mark each screen the hero steps foot in as visited
409 14309416 }
410
411 // TODO: should add a moveflag to sprites to configure the size of this rect (or effectively disable
412 // freezing if the rect returns is large enough). See:
413 // https://discord.com/channels/876899628556091432/1358483603700449581
414 // https://discord.com/channels/876899628556091432/1130384911983980554
415 //
416 85866675 viewport_t get_sprite_freeze_rect()
417 {
418 85866675 viewport_t freeze_rect = viewport;
419 85866675 int tile_buffer = 3;
420 85866675 freeze_rect.w += 16 * tile_buffer * 2;
421 85866675 freeze_rect.h += 16 * tile_buffer * 2;
422 85866675 freeze_rect.x -= 16 * tile_buffer;
423 85866675 freeze_rect.y -= 16 * tile_buffer;
424 85866675 return freeze_rect;
425 }
426
427 4722 mapscr* determine_hero_screen_from_coords()
428 {
429 4722 int x = vbound(Hero.getX().getInt(), 0, world_w - 1);
430 4722 int y = vbound(Hero.getY().getInt(), 0, world_h - 1);
431 4722 int dx = x / 256;
432 4722 int dy = y / 176;
433 4722 return get_scr(cur_screen + dx + dy * 16);
434 }
435
436 26924 bool edge_of_region(direction dir)
437 {
438
2/2
✓ Branch 0 taken 26844 times.
✓ Branch 1 taken 80 times.
26924 if (!is_in_scrolling_region()) return true;
439
440 80 int screen_x = hero_screen % 16;
441 80 int screen_y = hero_screen / 16;
442
2/2
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 2 times.
80 if (dir == up) screen_y -= 1;
443
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 10 times.
80 if (dir == down) screen_y += 1;
444
2/2
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 30 times.
80 if (dir == left) screen_x -= 1;
445
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 38 times.
80 if (dir == right) screen_x += 1;
446
4/8
✓ Branch 0 taken 80 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 80 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 80 times.
✗ Branch 7 not taken.
80 if (screen_x < 0 || screen_x > 16 || screen_y < 0 || screen_y > 8) return true;
447 80 return !is_in_current_region(map_scr_xy_to_index(screen_x, screen_y));
448 26924 }
449
450 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
451 // Coordinates are clamped to the world bounds.
452 211927537 int get_screen_for_world_xy(int x, int y)
453 {
454
2/2
✓ Branch 0 taken 189158517 times.
✓ Branch 1 taken 22769020 times.
211927537 if (!is_in_scrolling_region())
455 189158517 return cur_screen;
456
457 22769020 int dx = std::clamp(x, 0, world_w - 1) / 256;
458 22769020 int dy = std::clamp(y, 0, world_h - 1) / 176;
459 22769020 int origin_screen_x = cur_screen % 16;
460 22769020 int origin_screen_y = cur_screen / 16;
461 22769020 int scr_x = origin_screen_x + dx;
462 22769020 int scr_y = origin_screen_y + dy;
463 22769020 return map_scr_xy_to_index(scr_x, scr_y);
464 211927537 }
465
466 32474370 int get_screen_for_rpos(rpos_t rpos)
467 {
468 32474370 int origin_screen_x = cur_screen % 16;
469 32474370 int origin_screen_y = cur_screen / 16;
470 32474370 int screen = static_cast<int32_t>(rpos) / 176;
471 32474370 int scr_x = origin_screen_x + screen%cur_region.screen_width;
472 32474370 int scr_y = origin_screen_y + screen/cur_region.screen_width;
473 32474370 return map_scr_xy_to_index(scr_x, scr_y);
474 }
475
476 774202713 rpos_handle_t get_rpos_handle(rpos_t rpos, int layer)
477 {
478 DCHECK_LAYER_ZERO_INDEX(layer);
479
2/2
✓ Branch 0 taken 741866303 times.
✓ Branch 1 taken 32336410 times.
774202713 if (!is_in_scrolling_region())
480 741866303 return {get_scr_layer(cur_screen, layer), cur_screen, layer, rpos, RPOS_TO_POS(rpos)};
481 32336410 int screen = get_screen_for_rpos(rpos);
482 32336410 mapscr* scr = get_scr_layer(screen, layer);
483 32336410 return {scr, screen, layer, rpos, RPOS_TO_POS(rpos)};
484 774202713 }
485
486 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
487 // Coordinates are clamped to the world bounds.
488 3492100532 rpos_handle_t get_rpos_handle_for_world_xy(int x, int y, int layer)
489 {
490 3492100532 x = std::clamp(x, 0, world_w - 1);
491 3492100532 y = std::clamp(y, 0, world_h - 1);
492
493 DCHECK_LAYER_ZERO_INDEX(layer);
494
2/2
✓ Branch 0 taken 3464385752 times.
✓ Branch 1 taken 27714780 times.
3492100532 if (!is_in_scrolling_region())
495 {
496 3464385752 int pos = COMBOPOS(x, y);
497 3464385752 return {get_scr_layer(cur_screen, layer), cur_screen, layer, (rpos_t)pos, pos};
498 }
499 27714780 return get_rpos_handle(COMBOPOS_REGION(x, y), layer);
500 3492100532 }
501
502 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
503 1926 rpos_handle_t get_rpos_handle_for_screen(int screen, int layer, int pos)
504 {
505 DCHECK_LAYER_ZERO_INDEX(layer);
506 1926 return {get_scr_layer(screen, layer), screen, layer, POS_TO_RPOS(pos, screen), pos};
507 }
508
509 // Return a rpos_handle_t for a screen-specific `pos` (0-175).
510 // Use this instead of the other `get_pos_handle_for_screen` if you already have a reference to the screen.
511 62247 rpos_handle_t get_rpos_handle_for_scr(mapscr* scr, int layer, int pos)
512 {
513 DCHECK_LAYER_ZERO_INDEX(layer);
514 62247 return {scr, scr->screen, layer, POS_TO_RPOS(pos, scr->screen), pos};
515 }
516
517 25183265 void change_rpos_handle_layer(rpos_handle_t& rpos_handle, int layer)
518 {
519 DCHECK_LAYER_ZERO_INDEX(layer);
520 25183265 rpos_handle.layer = layer;
521 25183265 rpos_handle.scr = get_scr_layer(rpos_handle.screen, layer);
522 25183265 }
523
524 // x, y are world coordinates (aka, in relation to origin screen at the top-left).
525 // Coordinates are clamped to the world bounds.
526 52808 combined_handle_t get_combined_handle_for_world_xy(int x, int y, int layer)
527 {
528 DCHECK_LAYER_ZERO_INDEX(layer);
529
530 52808 x = std::clamp(x, 0, world_w - 1);
531 52808 y = std::clamp(y, 0, world_h - 1);
532
533 52808 auto maybe_ffc_handle = getFFCAt(x, y);
534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (maybe_ffc_handle)
535 return maybe_ffc_handle.value();
536
537 52808 auto rpos = COMBOPOS_REGION_B(x, y);
538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 52808 times.
52808 if (rpos == rpos_t::None)
539 return rpos_handle_t();
540 52808 return get_rpos_handle(rpos, layer);
541 52808 }
542
543 // These functions all return _temporary_ screens. Any modifications made to them (either by the engine
544 // directly or via zscript) only last until the next area is loaded (via loadscr).
545
546 // Returns the screen containing the (x, y) world position.
547 1633839945 mapscr* get_scr_for_world_xy(int x, int y)
548 {
549 // Quick path, but should work the same without.
550
2/2
✓ Branch 0 taken 1622710689 times.
✓ Branch 1 taken 11129256 times.
1633839945 if (!is_in_scrolling_region()) return origin_scr;
551 11129256 return get_scr(get_screen_for_world_xy(x, y));
552 1633839945 }
553
554 24512760 mapscr* get_scr_for_rpos(rpos_t rpos)
555 {
556 // Quick path, but should work the same without.
557
2/2
✓ Branch 0 taken 24374814 times.
✓ Branch 1 taken 137946 times.
24512760 if (!is_in_scrolling_region()) return origin_scr;
558 137946 return get_scr(get_screen_for_rpos(rpos));
559 24512760 }
560
561 14 mapscr* get_scr_for_rpos_layer(rpos_t rpos, int layer)
562 {
563 14 return get_scr_layer(get_screen_for_rpos(rpos), layer);
564 }
565
566 // Note: layer=0 is the base screen, 1 is the first layer, etc.
567 2308652236 mapscr* get_scr_for_world_xy_layer(int x, int y, int layer)
568 {
569 DCHECK_LAYER_ZERO_INDEX(layer);
570
2/2
✓ Branch 0 taken 2297232238 times.
✓ Branch 1 taken 11419998 times.
2308652236 if (!is_in_scrolling_region()) return get_scr_layer(cur_screen, layer);
571
2/2
✓ Branch 0 taken 708934 times.
✓ Branch 1 taken 10711064 times.
11419998 return layer == 0 ?
572 708934 get_scr_for_world_xy(x, y) :
573 10711064 get_scr_layer(get_screen_for_world_xy(x, y), layer);
574 2308652236 }
575
576 1833551791 int get_region_screen_offset(int screen)
577 {
578 1833551791 return get_region_relative_dx(screen) + get_region_relative_dy(screen) * cur_region.screen_width;
579 }
580
581 654676687 int get_screen_for_region_index_offset(int offset)
582 {
583 654676687 int scr_dx = offset % cur_region.screen_width;
584 654676687 int scr_dy = offset / cur_region.screen_width;
585 654676687 int screen = cur_screen + scr_dx + scr_dy*16;
586 654676687 return screen;
587 }
588
589 654492850 mapscr* get_scr_for_region_index_offset(int offset)
590 {
591 654492850 int screen = get_screen_for_region_index_offset(offset);
592 654492850 return get_scr(screen);
593 }
594
595 // The screen at (map, screen) must exist.
596 1421712010 mapscr* get_scr(int map, int screen)
597 {
598 1421712010 mapscr* scr = get_scr_maybe(map, screen);
599
1/2
✓ Branch 0 taken 1421712010 times.
✗ Branch 1 not taken.
1421712010 CHECK(scr);
600 1421712010 return scr;
601 }
602
603 837452985 mapscr* get_scr(int screen)
604 {
605 837452985 return get_scr(cur_map, screen);
606 }
607
608 // Returns null if active screen does not exist.
609 1451257053 mapscr* get_scr_maybe(int map, int screen)
610 {
611 DCHECK_RANGE_INCLUSIVE(screen, 0, 135);
612
613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1451257053 times.
1451257053 if (map == cur_map)
614 {
615
2/2
✓ Branch 0 taken 1430487371 times.
✓ Branch 1 taken 20769682 times.
1451257053 if (screen == cur_screen)
616 1430487371 return origin_scr;
617
618 20769682 int index = screen*7;
619
2/2
✓ Branch 0 taken 20758592 times.
✓ Branch 1 taken 11090 times.
20769682 if (temporary_screens[index])
620 20758592 return temporary_screens[index];
621
622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (screen == home_screen)
623 return special_warp_return_scr;
624 11090 }
625
626
3/6
✓ Branch 0 taken 11090 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11090 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11090 times.
11090 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
627 {
628 11090 int index = screen*7;
629
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11090 times.
11090 if (FFCore.ScrollingScreensAll[index])
630 11090 return FFCore.ScrollingScreensAll[index];
631 }
632
633 return nullptr;
634 1451257053 }
635
636 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
637 7053190316 mapscr* get_scr_layer(int map, int screen, int layer)
638 {
639 DCHECK_LAYER_ZERO_INDEX(layer);
640
2/2
✓ Branch 0 taken 6471424017 times.
✓ Branch 1 taken 581766299 times.
7053190316 if (layer == 0)
641 581766299 return get_scr(map, screen);
642
643
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6471424017 times.
6471424017 if (map == cur_map)
644 {
645 6471424017 int index = screen*7 + layer;
646
2/2
✓ Branch 0 taken 6471355617 times.
✓ Branch 1 taken 68400 times.
6471424017 if (temporary_screens[index])
647 6471355617 return temporary_screens[index];
648
649
2/2
✓ Branch 0 taken 1860 times.
✓ Branch 1 taken 66540 times.
68400 if (screen == home_screen)
650 1860 return &special_warp_return_scrs[layer];
651 66540 }
652
653
1/2
✓ Branch 0 taken 66540 times.
✗ Branch 1 not taken.
66540 if (screenscrolling && map == scrolling_map && !FFCore.ScrollingScreensAll.empty())
654 {
655 66540 int index = screen*7 + layer;
656
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66540 times.
66540 if (FFCore.ScrollingScreensAll[index])
657 66540 return FFCore.ScrollingScreensAll[index];
658 }
659
660 NOTREACHED();
661 7053190316 }
662
663 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
664 6654044200 mapscr* get_scr_layer(int screen, int layer)
665 {
666 6654044200 return get_scr_layer(cur_map, screen, layer);
667 }
668
669 // Note: layer=0 returns the base screen, layer=1 returns the first layer.
670 // Return nullptr if screen is not valid.
671 397072313 mapscr* get_scr_layer_valid(int screen, int layer)
672 {
673
2/2
✓ Branch 0 taken 78265267 times.
✓ Branch 1 taken 318807046 times.
397072313 if (mapscr* scr = get_scr_layer(cur_map, screen, layer); scr->is_valid())
674 78265267 return scr;
675 318807046 return nullptr;
676 397072313 }
677
678 401 mapscr* get_scr_current_region_dir(int screen, direction dir)
679 {
680 401 int x = get_region_relative_dx(screen);
681 401 int y = get_region_relative_dy(screen);
682
3/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 330 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 71 times.
401 if (dir == left && x == 0)
683 71 return nullptr;
684
3/4
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 238 times.
✓ Branch 2 taken 92 times.
✗ Branch 3 not taken.
330 if (dir == right && x == 15)
685 return nullptr;
686
3/4
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 281 times.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
330 if (dir == down && y == 7)
687 return nullptr;
688
3/4
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 141 times.
✓ Branch 2 taken 189 times.
✗ Branch 3 not taken.
330 if (dir == up && y == 0)
689 189 return nullptr;
690
691 141 screen = screen_index_direction(screen, dir);
692
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 141 times.
141 if (is_in_current_region(screen))
693 return get_scr(screen);
694
695 141 return nullptr;
696 401 }
697
698 183837 ffc_handle_t get_ffc_handle(ffc_id_t id)
699 {
700 183837 uint8_t screen = get_screen_for_region_index_offset(id / MAXFFCS);
701 183837 uint8_t i = id % MAXFFCS;
702 183837 mapscr* scr = get_scr(screen);
703 183837 ffcdata* ffc = &scr->getFFC(id % MAXFFCS);
704 183837 return {scr, screen, id, i, ffc};
705 }
706
707 34566 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen, int x, int y)
708 {
709 34566 x += get_region_relative_dx(screen) * 256;
710 34566 y += get_region_relative_dy(screen) * 176;
711 34566 return {x, y};
712 }
713
714 1049500 std::pair<int32_t, int32_t> translate_screen_coordinates_to_world(int screen)
715 {
716 1049500 int x = get_region_relative_dx(screen) * 256;
717 1049500 int y = get_region_relative_dy(screen) * 176;
718 1049500 return {x, y};
719 }
720
721 12130064600 int32_t COMBOPOS(int32_t x, int32_t y)
722 {
723 DCHECK(x >= 0 && x < 256 && y >= 0 && y < 176);
724 12130064600 return (y & 0xF0) + (x >> 4);
725 }
726 int32_t COMBOPOS_B(int32_t x, int32_t y)
727 {
728 if(unsigned(x) >= 256 || unsigned(y) >= 176)
729 return -1;
730 return (y & 0xF0) + (x >> 4);
731 }
732 3334371711 int32_t COMBOX(int32_t pos)
733 {
734 3334371711 return pos % 16 * 16;
735 }
736 3334371711 int32_t COMBOY(int32_t pos)
737 {
738 3334371711 return pos & 0xF0;
739 }
740
741 112600455 rpos_t COMBOPOS_REGION(int32_t x, int32_t y)
742 {
743
2/2
✓ Branch 0 taken 84070201 times.
✓ Branch 1 taken 28530254 times.
112600455 if (!is_in_scrolling_region())
744 84070201 return (rpos_t) COMBOPOS(x, y);
745
746 DCHECK(is_in_world_bounds(x, y));
747 28530254 int scr_dx = x / (16*16);
748 28530254 int scr_dy = y / (11*16);
749 28530254 int pos = COMBOPOS(x%256, y%176);
750 28530254 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
751 112600455 }
752 6305040380 rpos_t COMBOPOS_REGION_B(int32_t x, int32_t y)
753 {
754
2/2
✓ Branch 0 taken 1400932 times.
✓ Branch 1 taken 6303639448 times.
6305040380 if (!is_in_world_bounds(x, y))
755 1400932 return rpos_t::None;
756
757 6303639448 int scr_dx = x / (16*16);
758 6303639448 int scr_dy = y / (11*16);
759 6303639448 int pos = COMBOPOS(x%256, y%176);
760 6303639448 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + pos);
761 6305040380 }
762 25287068 std::pair<int32_t, int32_t> COMBOXY_REGION(rpos_t rpos)
763 {
764 25287068 int scr_index = static_cast<int32_t>(rpos) / 176;
765 25287068 int scr_dx = scr_index % cur_region.screen_width;
766 25287068 int scr_dy = scr_index / cur_region.screen_width;
767 25287068 int pos = RPOS_TO_POS(rpos);
768 25287068 int x = scr_dx*16*16 + COMBOX(pos);
769 25287068 int y = scr_dy*11*16 + COMBOY(pos);
770 25287068 return {x, y};
771 }
772 60396 int32_t COMBOX_REGION(rpos_t rpos)
773 {
774 60396 auto [x, y] = COMBOXY_REGION(rpos);
775 60396 return x;
776 }
777 12225 int32_t COMBOY_REGION(rpos_t rpos)
778 {
779 12225 auto [x, y] = COMBOXY_REGION(rpos);
780 12225 return y;
781 }
782
783 70177 rpos_t COMBOPOS_REGION_INDEX(int32_t x, int32_t y)
784 {
785 DCHECK(is_in_world_bounds(x, y));
786
1/2
✓ Branch 0 taken 70177 times.
✗ Branch 1 not taken.
70177 if (!is_in_scrolling_region())
787 70177 return (rpos_t)(x + y * 16);
788
789 int scr_dx = x / 16;
790 int scr_dy = y / 11;
791 x %= 16;
792 y %= 11;
793 return static_cast<rpos_t>((scr_dx + scr_dy * cur_region.screen_width)*176 + x + y * 16);
794 70177 }
795 70632 std::pair<int32_t, int32_t> COMBOXY_REGION_INDEX(rpos_t rpos)
796 {
797 70632 int scr_index = static_cast<int32_t>(rpos) / 176;
798 70632 int scr_dx = scr_index % cur_region.screen_width;
799 70632 int scr_dy = scr_index / cur_region.screen_width;
800 70632 int pos = RPOS_TO_POS(rpos);
801 70632 int x = scr_dx*16 + pos%16;
802 70632 int y = scr_dy*11 + pos/16;
803 70632 return {x, y};
804 }
805
806 88504176 int32_t mapind(int32_t map, int32_t scr)
807 {
808 88504176 return map * MAPSCRSNORMAL + scr;
809 }
810
811 FONT *get_zc_font(int index);
812
813 extern sprite_list guys, items, Ewpns, Lwpns, chainlinks, decorations;
814 extern movingblock mblock2; //mblock[4]?
815 extern portal mirror_portal;
816
817 void Z_message_d(const char *format,...)
818 {
819 #ifdef _DEBUG
820 char buf[512];
821 va_list ap;
822 va_start(ap, format);
823 vsprintf(buf, format, ap);
824 va_end(ap);
825
826 al_trace("%s",buf);
827 #else
828 format=format;
829 #endif
830 }
831
832
833
834 bool checktrigger=false;
835
836 void debugging_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2)
837 {
838 //reference/optimization: the start of the unused drawing command index can now be queried. -Gleeok
839 int32_t index = script_drawing_commands.GetNext();
840
841 if(index < 0)
842 return;
843
844 int32_t *sdci = &script_drawing_commands[index][0];
845
846 sdci[0] = RECTR;
847 sdci[1] = 30000;
848 sdci[2] = x1*10000;
849 sdci[3] = y1*10000;
850 sdci[4] = x2*10000;
851 sdci[5] = y2*10000;
852 sdci[6] = 10000;
853 sdci[7] = 10000;
854 sdci[8] = 0;
855 sdci[9] = 0;
856 sdci[10] = 0;
857 sdci[11] = 10000;
858 sdci[12] = 1280000;
859 }
860
861 void clear_dmap(word i)
862 {
863 DMaps[i].clear();
864 }
865
866 void clear_dmaps()
867 {
868 for(int32_t i=0; i<MAXDMAPS; i++)
869 {
870 clear_dmap(i);
871 }
872 }
873
874 223615827 int32_t isdungeon(int32_t dmap, int32_t screen)
875 {
876
2/2
✓ Branch 0 taken 223570147 times.
✓ Branch 1 taken 45680 times.
223615827 if (dmap < 0) dmap = cur_dmap;
877
878 // dungeons can have any dlevel above 0
879
2/2
✓ Branch 0 taken 122366382 times.
✓ Branch 1 taken 101249445 times.
223615827 if((DMaps[dmap].type&dmfTYPE) == dmDNGN)
880 {
881
2/2
✓ Branch 0 taken 9961 times.
✓ Branch 1 taken 101239484 times.
101249445 if (get_canonical_scr(cur_map, screen)->flags6&fCAVEROOM)
882 9961 return 0;
883
884 101239484 return 1;
885 }
886
887 // dlevels that aren't dungeons are caves
888
2/2
✓ Branch 0 taken 36827 times.
✓ Branch 1 taken 122329555 times.
122366382 if (get_canonical_scr(cur_map, screen)->flags6&fDUNGEONROOM)
889 36827 return 1;
890
891 122329555 return 0;
892 223615827 }
893
894 39942476 int32_t isdungeon(int32_t screen)
895 {
896 39942476 return isdungeon(cur_dmap, screen);
897 }
898
899 183546414 int32_t isdungeon()
900 {
901 183546414 return isdungeon(cur_dmap, hero_screen);
902 }
903
904 88932 bool canPermSecret(int32_t dmap, int32_t screen)
905 {
906
2/2
✓ Branch 0 taken 13910 times.
✓ Branch 1 taken 75022 times.
88932 return (!isdungeon(dmap, screen) || get_qr(qr_DUNGEON_DMAPS_PERM_SECRETS));
907 }
908
909 1375697461 int32_t MAPCOMBO(int32_t x, int32_t y)
910 {
911 1375697461 x = vbound(x, 0, world_w-1);
912 1375697461 y = vbound(y, 0, world_h-1);
913 1375697461 int pos = COMBOPOS(x%256, y%176);
914 1375697461 mapscr* scr = get_scr_for_world_xy(x, y);
915 1375697461 return scr->data[pos];
916 }
917
918 //specific layers 1 to 6
919 1709728262 int32_t MAPCOMBOL(int32_t layer,int32_t x,int32_t y)
920 {
921 DCHECK(layer >= 1 && layer <= 6);
922
3/4
✓ Branch 0 taken 1689370280 times.
✓ Branch 1 taken 20357982 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1689370280 times.
1709728262 if (!is_in_world_bounds(x, y) || layer <= 0)
923 20357982 return 0;
924
925 1689370280 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
926
2/2
✓ Branch 0 taken 496888043 times.
✓ Branch 1 taken 1192482237 times.
1689370280 if (!m->is_valid())
927 1192482237 return 0;
928
929 496888043 int pos = COMBOPOS(x%256, y%176);
930 496888043 return m->data[pos];
931 1709728262 }
932
933 int32_t MAPCSETL(int32_t layer,int32_t x,int32_t y)
934 {
935 DCHECK(layer >= 1 && layer <= 6);
936 if (!is_in_world_bounds(x, y) || layer <= 0)
937 return 0;
938
939 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
940 if (!m->is_valid())
941 return 0;
942
943 int pos = COMBOPOS(x%256, y%176);
944 return m->cset[pos];
945 }
946
947 189308 int32_t MAPFLAGL(int32_t layer,int32_t x,int32_t y)
948 {
949 DCHECK(layer >= 1 && layer <= 6);
950
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
951 return 0;
952
953 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
954
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
955 40394 return 0;
956
957 148914 int pos = COMBOPOS(x%256, y%176);
958 148914 return m->sflag[pos];
959 189308 }
960
961 6281 int32_t COMBOTYPEL(int32_t layer,int32_t x,int32_t y)
962 {
963 DCHECK(layer >= 1 && layer <= 6);
964
2/4
✓ Branch 0 taken 6281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6281 times.
6281 if (!is_in_world_bounds(x, y) || layer <= 0)
965 return 0;
966
967 6281 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
968
2/2
✓ Branch 0 taken 5809 times.
✓ Branch 1 taken 472 times.
6281 if (!m->is_valid())
969 472 return 0;
970
971 5809 int pos = COMBOPOS(x%256, y%176);
972 5809 return combobuf[m->data[pos]].type;
973 6281 }
974
975 189308 int32_t MAPCOMBOFLAGL(int32_t layer,int32_t x,int32_t y)
976 {
977 DCHECK(layer >= 1 && layer <= 6);
978
2/4
✓ Branch 0 taken 189308 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 189308 times.
189308 if (!is_in_world_bounds(x, y) || layer <= 0)
979 return 0;
980
981 189308 mapscr* m = get_scr_for_world_xy_layer(x, y, layer);
982
2/2
✓ Branch 0 taken 148914 times.
✓ Branch 1 taken 40394 times.
189308 if (!m->is_valid())
983 40394 return 0;
984
985 148914 int pos = COMBOPOS(x%256, y%176);
986 148914 return combobuf[m->data[pos]].flag;
987 189308 }
988
989
990 // True if the FFC covers x, y and is not ethereal or a changer.
991 2467474540 bool ffcIsAt(const ffc_handle_t& ffc_handle, int32_t x, int32_t y)
992 {
993
2/2
✓ Branch 0 taken 746713622 times.
✓ Branch 1 taken 1720760918 times.
2467474540 if (ffc_handle.data()<=0)
994 746713622 return false;
995
996
2/2
✓ Branch 0 taken 300866324 times.
✓ Branch 1 taken 1419894594 times.
1720760918 if((ffc_handle.ffc->flags&(ffc_changer|ffc_ethereal))!=0)
997 300866324 return false;
998
999 1419894594 int32_t fx=ffc_handle.ffc->x.getInt();
1000
4/4
✓ Branch 0 taken 976324807 times.
✓ Branch 1 taken 443569787 times.
✓ Branch 2 taken 866195279 times.
✓ Branch 3 taken 110129528 times.
1419894594 if(x<fx || x>fx+(ffc_handle.scr->ffEffectWidth(ffc_handle.i)-1)) // FFC sizes are weird.
1001 1309765066 return false;
1002
1003 110129528 int32_t fy=ffc_handle.ffc->y.getInt();
1004
4/4
✓ Branch 0 taken 80145923 times.
✓ Branch 1 taken 29983605 times.
✓ Branch 2 taken 60078215 times.
✓ Branch 3 taken 20067708 times.
110129528 if(y<fy || y>fy+(ffc_handle.scr->ffEffectHeight(ffc_handle.i)-1))
1005 90061820 return false;
1006
1007 20067708 return true;
1008 2467474540 }
1009
1010 999075493 int32_t MAPFFCOMBO(int32_t x,int32_t y)
1011 {
1012
2/2
✓ Branch 0 taken 13163663 times.
✓ Branch 1 taken 985911830 times.
999075493 if (auto ffc_handle = getFFCAt(x, y))
1013 13163663 return ffc_handle->data();
1014 985911830 return 0;
1015 999075493 }
1016
1017 207232 int32_t MAPCSET(int32_t x, int32_t y)
1018 {
1019
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 207232 times.
207232 if (!is_in_world_bounds(x, y))
1020 return 0;
1021 207232 mapscr* scr = get_scr_for_world_xy(x, y);
1022 207232 int pos = COMBOPOS(x%256, y%176);
1023 207232 return scr->cset[pos];
1024 207232 }
1025
1026 73664988 int32_t MAPFLAG(int32_t x, int32_t y)
1027 {
1028
2/2
✓ Branch 0 taken 28140 times.
✓ Branch 1 taken 73636848 times.
73664988 if (!is_in_world_bounds(x, y))
1029 28140 return 0;
1030 73636848 mapscr* scr = get_scr_for_world_xy(x, y);
1031 73636848 int pos = COMBOPOS(x%256, y%176);
1032 73636848 return scr->sflag[pos];
1033 73664988 }
1034
1035 163184591 int32_t COMBOTYPE(int32_t x,int32_t y)
1036 {
1037 163184591 int32_t b=1;
1038
2/2
✓ Branch 0 taken 95232965 times.
✓ Branch 1 taken 67951626 times.
163184591 if(x&8) b<<=2;
1039
2/2
✓ Branch 0 taken 81540582 times.
✓ Branch 1 taken 81644009 times.
163184591 if(y&8) b<<=1;
1040
1041
2/2
✓ Branch 0 taken 326362144 times.
✓ Branch 1 taken 163177292 times.
489539436 for (int32_t i = 0; i <= 1; ++i)
1042 {
1043
2/2
✓ Branch 0 taken 316029196 times.
✓ Branch 1 taken 10332948 times.
326362144 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1044 {
1045
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 316029196 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
316029196 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x, y, i)) return cNONE;
1046 316029196 }
1047 else
1048 {
1049
4/4
✓ Branch 0 taken 10451 times.
✓ Branch 1 taken 10322497 times.
✓ Branch 2 taken 3152 times.
✓ Branch 3 taken 7299 times.
10332948 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x, y, i)) return cNONE;
1050 }
1051 326354845 }
1052
1053 163177292 newcombo const& cmb = combobuf[MAPCOMBO(x,y)];
1054
5/6
✓ Branch 0 taken 3590234 times.
✓ Branch 1 taken 159587058 times.
✓ Branch 2 taken 3030548 times.
✓ Branch 3 taken 559686 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 3030548 times.
163177292 if (cmb.type == cWATER && (cmb.walk&b) && ((cmb.walk>>4)&b))
1055 {
1056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3030548 times.
3030548 if(cmb.usrflags&cflag4) return cSHALLOWWATER;
1057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3030548 times.
3030548 if(cmb.usrflags&cflag3) return cNONE;
1058 3030548 }
1059 163177292 return cmb.type;
1060 163184591 }
1061
1062 50225603 int32_t FFCOMBOTYPE(int32_t x,int32_t y)
1063 {
1064 50225603 return combobuf[MAPFFCOMBO(x,y)].type;
1065 }
1066
1067 4954844 int32_t FFORCOMBO(int32_t x, int32_t y)
1068 {
1069
2/2
✓ Branch 0 taken 58516 times.
✓ Branch 1 taken 4896328 times.
4954844 if (auto ffc_handle = getFFCAt(x, y))
1070 58516 return ffc_handle->data();
1071
1072 4896328 return MAPCOMBO(x,y);
1073 4954844 }
1074
1075 int32_t FFORCOMBOTYPE(int32_t x, int32_t y)
1076 {
1077 for (int32_t i = 0; i <= 1; ++i)
1078 {
1079 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1080 {
1081 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1082 }
1083 else
1084 {
1085 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1086 }
1087 }
1088 int32_t b=1;
1089
1090 if(x&8) b<<=2;
1091
1092 if(y&8) b<<=1;
1093 newcombo const& cmb = combobuf[FFORCOMBO(x,y)];
1094 if (cmb.type == cWATER && (cmb.usrflags&cflag4) && (cmb.walk&b)) return cSHALLOWWATER;
1095 if (cmb.type == cWATER && (cmb.usrflags&cflag3) && (cmb.walk&b)) return cNONE;
1096 return cmb.type;
1097 }
1098
1099 int32_t FFORCOMBO_L(int32_t layer, int32_t x, int32_t y)
1100 {
1101 if (auto ffc_handle = getFFCAt(x, y))
1102 return ffc_handle->data();
1103
1104 return layer ? MAPCOMBOL(layer, x, y) : MAPCOMBO(x,y);
1105 }
1106
1107 int32_t FFORCOMBOTYPE_L(int32_t layer, int32_t x, int32_t y)
1108 {
1109 return combobuf[FFORCOMBO_L(layer,x,y)].type;
1110 }
1111
1112 70154870 int32_t MAPCOMBOFLAG(int32_t x,int32_t y)
1113 {
1114
2/2
✓ Branch 0 taken 27852 times.
✓ Branch 1 taken 70127018 times.
70154870 if (!is_in_world_bounds(x, y))
1115 27852 return 0;
1116
1117 70127018 mapscr* scr = get_scr_for_world_xy(x, y);
1118 70127018 int pos = COMBOPOS(x%256, y%176);
1119 70127018 return combobuf[scr->data[pos]].flag;
1120 70154870 }
1121
1122 56841587 int32_t MAPFFCOMBOFLAG(int32_t x,int32_t y)
1123 {
1124
2/2
✓ Branch 0 taken 746177 times.
✓ Branch 1 taken 56095410 times.
56841587 if (auto ffc_handle = getFFCAt(x, y))
1125 746177 return ffc_handle->cflag();
1126
1127 56095410 return 0;
1128 56841587 }
1129
1130 1313056294 std::optional<ffc_handle_t> getFFCAt(int32_t x, int32_t y)
1131 {
1132 2788859658 return find_ffc([&](const ffc_handle_t& ffc_handle) {
1133 1475803364 return ffcIsAt(ffc_handle, x, y);
1134 });
1135 }
1136
1137 3044 int32_t MAPCOMBO(const rpos_handle_t& rpos_handle)
1138 {
1139
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3044 times.
3044 if (!rpos_handle.scr->is_valid()) return 0;
1140 3044 return rpos_handle.data();
1141 3044 }
1142
1143 3161196735 int32_t MAPCOMBO2(int32_t layer, int32_t x, int32_t y)
1144 {
1145 DCHECK_LAYER_NEG1_INDEX(layer);
1146
2/2
✓ Branch 0 taken 22360696 times.
✓ Branch 1 taken 3138836039 times.
3161196735 if (!is_in_world_bounds(x, y)) return 0;
1147
2/2
✓ Branch 0 taken 3067238952 times.
✓ Branch 1 taken 71597087 times.
3138836039 if (layer == -1) return MAPCOMBO(x, y);
1148
1149 3067238952 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1150
2/2
✓ Branch 0 taken 2111914889 times.
✓ Branch 1 taken 955324063 times.
3067238952 if (!rpos_handle.scr->is_valid()) return 0;
1151
1152 955324063 return rpos_handle.data();
1153 3161196735 }
1154
1155 17372399 static void _handle_screen_load_trigger(const combined_handle_t& handle)
1156 {
1157 17372399 auto cid = handle.data();
1158 17372399 auto* cmb = &handle.combo();
1159 17372399 bool done = false;
1160 17372399 std::set<int32_t> visited;
1161
2/2
✓ Branch 0 taken 17372399 times.
✓ Branch 1 taken 17372399 times.
34744798 while(!done)
1162 {
1163
2/4
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372399 times.
17372399 if(visited.contains(cid))
1164 {
1165 Z_error("Combo '%d' was part of an infinite trigger loop, breaking out of loop", cid);
1166 break; // prevent infinite loop
1167 }
1168
1/2
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
17372399 visited.insert(cid);
1169
1170 17372399 done = true; // don't loop again unless something changes
1171
1/2
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
17964354 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
1172 591955 return trig.trigger_flags.get(TRIGFLAG_SCREENLOAD);
1173 });
1174
2/4
✓ Branch 0 taken 17372399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17372399 times.
17372399 if(handle.data() != cid)
1175 {
1176 cid = handle.data();
1177 cmb = &handle.combo();
1178 done = false; // loop again for the new combo
1179 }
1180 }
1181 17372399 }
1182 51768 static void handle_screen_load_trigger(const screen_handles_t& screen_handles)
1183 {
1184 51768 for_every_combo_in_screen(screen_handles, _handle_screen_load_trigger);
1185 51768 }
1186 34820 void handle_region_load_trigger()
1187 {
1188
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 34668 times.
34820 if (is_in_scrolling_region())
1189 {
1190
2/2
✓ Branch 0 taken 152 times.
✓ Branch 1 taken 19456 times.
19608 for (int screen = 0; screen < 128; screen++)
1191 {
1192
2/2
✓ Branch 0 taken 18156 times.
✓ Branch 1 taken 1300 times.
19456 if (is_in_current_region(screen))
1193 1300 handle_screen_load_trigger(create_screen_handles_one(get_scr(screen)));
1194 19456 }
1195 152 }
1196 34668 else handle_screen_load_trigger(create_screen_handles_one(get_scr(hero_screen)));
1197 34820 }
1198
1199 15800 static void apply_state_changes_to_screen(mapscr& scr, int32_t map, int32_t screen, int32_t flags, bool secrets_do_replay_comment)
1200 {
1201 15800 auto screen_handles = create_screen_handles_one(&scr);
1202
1203
3/4
✓ Branch 0 taken 539 times.
✓ Branch 1 taken 15261 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 539 times.
15800 if ((flags & mSECRET) && canPermSecret(cur_dmap, screen))
1204 {
1205 539 reveal_hidden_stairs(&scr, screen, false);
1206 539 bool do_layers = false;
1207 539 bool from_active_screen = false;
1208 539 trigger_secrets_for_screen_internal(screen_handles, do_layers, from_active_screen, -3, secrets_do_replay_comment);
1209 539 }
1210
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if (flags & mLIGHTBEAM)
1211 {
1212 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
1213 if (rpos_handle.ctype() == cLIGHTTARGET)
1214 {
1215 if (!(rpos_handle.combo().usrflags&cflag1)) //Unlit version
1216 rpos_handle.increment_data();
1217 }
1218 });
1219 }
1220
1221 15800 int lvl = DMaps[cur_dmap].level;
1222 15800 toggle_switches(game->lvlswitches[lvl], true, screen_handles);
1223 15800 toggle_gswitches_load(screen_handles);
1224
1225
2/2
✓ Branch 0 taken 15708 times.
✓ Branch 1 taken 92 times.
15800 if(flags&mLOCKBLOCK) // if special stuff done before
1226 {
1227 92 remove_screenstatecombos2(screen_handles, false, cLOCKBLOCK, cLOCKBLOCK2);
1228 92 }
1229
1230
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSLOCKBLOCK) // if special stuff done before
1231 {
1232 remove_screenstatecombos2(screen_handles, false, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
1233 }
1234
1235
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1236 {
1237 remove_screenstatecombos2(screen_handles, false, cCHEST, cCHEST2);
1238 }
1239
1240
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mCHEST) // if special stuff done before
1241 {
1242 remove_screenstatecombos2(screen_handles, false, cLOCKEDCHEST, cLOCKEDCHEST2);
1243 }
1244
1245
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 if(flags&mBOSSCHEST) // if special stuff done before
1246 {
1247 remove_screenstatecombos2(screen_handles, false, cBOSSCHEST, cBOSSCHEST2);
1248 }
1249
1250
1251 15800 int mi = mapind(map, screen);
1252 15800 clear_xdoors_mi(screen_handles, mi);
1253 15800 clear_xstatecombos_mi(screen_handles, mi);
1254
1255 15800 handle_screen_load_trigger(screen_handles);
1256 15800 }
1257
1258 53194 std::optional<mapscr> load_temp_mapscr_and_apply_secrets(int32_t map, int32_t screen, int32_t layer, bool secrets, bool secrets_do_replay_comment)
1259 {
1260
2/4
✓ Branch 0 taken 53194 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53194 times.
53194 if (map < 0 || screen < 0)
1261 return std::nullopt;
1262
1263 53194 const mapscr* source = get_canonical_scr(map, screen);
1264
2/2
✓ Branch 0 taken 40960 times.
✓ Branch 1 taken 12234 times.
53194 if (!source->is_valid())
1265 12234 return std::nullopt;
1266
1267
2/2
✓ Branch 0 taken 8308 times.
✓ Branch 1 taken 32652 times.
40960 if (layer >= 0)
1268 {
1269
2/2
✓ Branch 0 taken 25160 times.
✓ Branch 1 taken 7492 times.
32652 if (source->layermap[layer] <= 0)
1270 25160 return std::nullopt;
1271
1272 7492 source = get_canonical_scr(source->layermap[layer] - 1, source->layerscreen[layer]);
1273
1/2
✓ Branch 0 taken 7492 times.
✗ Branch 1 not taken.
7492 if (!source->is_valid())
1274 return std::nullopt;
1275 7492 }
1276
1277
1/2
✓ Branch 0 taken 15800 times.
✗ Branch 1 not taken.
15800 int flags = secrets ? game->maps[mapind(map, screen)] : 0;
1278 15800 mapscr scr = *source;
1279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15800 times.
15800 apply_state_changes_to_screen(scr, map, screen, flags, secrets_do_replay_comment);
1280
1281 15800 return scr;
1282 53194 }
1283
1284 27203 static int32_t MAPCOMBO3_impl(int32_t map, int32_t screen, int32_t layer, int32_t pos, bool secrets)
1285 {
1286
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if (map < 0 || screen < 0) return 0;
1287
1288
2/4
✓ Branch 0 taken 27203 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27203 times.
27203 if(pos>175 || pos < 0)
1289 return 0;
1290
1291 // TODO: consider caching this (invalidate on any modification via scripting, or anything
1292 // `apply_state_changes_to_screen` checks).
1293
4/5
✓ Branch 0 taken 4976 times.
✓ Branch 1 taken 22227 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4976 times.
✓ Branch 4 taken 22227 times.
32179 if (auto s = load_temp_mapscr_and_apply_secrets(map, screen, layer, secrets))
1294 4976 return s->data[pos];
1295
1296 22227 return 0;
1297 27203 }
1298
1299 // Read from the current temporary screens or, if (map, screen) is not loaded,
1300 // load that screen and apply the relevant secrets before evaluating the combo at that position.
1301 137734926 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets)
1302 {
1303 DCHECK_LAYER_NEG1_INDEX(layer);
1304 DCHECK(map >= 0 && screen >= 0);
1305
1306
2/2
✓ Branch 0 taken 137707723 times.
✓ Branch 1 taken 27203 times.
137734926 if (is_in_current_region(map, screen)) return MAPCOMBO2(layer, x, y);
1307
1308 // Screen is not in the current region, so we have to load and trigger some secrets.
1309 27203 int pos = COMBOPOS(x, y);
1310 27203 return MAPCOMBO3_impl(map, screen, layer, pos, secrets);
1311 137734926 }
1312
1313 int32_t MAPCOMBO3(int32_t map, int32_t screen, int32_t layer, rpos_t rpos, bool secrets)
1314 {
1315 DCHECK_LAYER_NEG1_INDEX(layer);
1316 DCHECK(map >= 0 && screen >= 0);
1317 DCHECK(is_valid_rpos(rpos));
1318
1319 if (is_in_current_region(map, screen)) return MAPCOMBO(get_rpos_handle(rpos, layer + 1));
1320
1321 // Screen is not currently loaded, so we have to load and trigger some secrets.
1322 return MAPCOMBO3_impl(map, screen, layer, RPOS_TO_POS(rpos), secrets);
1323 }
1324
1325 int32_t MAPCSET2(int32_t layer,int32_t x,int32_t y)
1326 {
1327 DCHECK_LAYER_NEG1_INDEX(layer);
1328 if (!is_in_world_bounds(x, y))
1329 return 0;
1330 if (layer == -1) return MAPCSET(x, y);
1331
1332 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1333 if (!rpos_handle.scr->is_valid()) return 0;
1334
1335 return rpos_handle.cset();
1336 }
1337
1338 98920838 int32_t MAPFLAG2(int32_t layer,int32_t x,int32_t y)
1339 {
1340 DCHECK_LAYER_NEG1_INDEX(layer);
1341
3/4
✓ Branch 0 taken 1894252 times.
✓ Branch 1 taken 97026586 times.
✓ Branch 2 taken 1894252 times.
✗ Branch 3 not taken.
98920838 if (!get_qr(qr_BUGGED_LAYERED_FLAGS) && (!is_in_world_bounds(x, y)))
1342 return 0;
1343
2/2
✓ Branch 0 taken 81313609 times.
✓ Branch 1 taken 17607229 times.
98920838 if (layer == -1) return MAPFLAG(x, y);
1344
1345 81313609 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1346
2/2
✓ Branch 0 taken 63007039 times.
✓ Branch 1 taken 18306570 times.
81313609 if (!rpos_handle.scr->is_valid()) return 0;
1347
1348 18306570 return rpos_handle.sflag();
1349 98920838 }
1350
1351 int32_t COMBOTYPE2(int32_t layer,int32_t x,int32_t y)
1352 {
1353 if(layer < 1)
1354 {
1355 for (int32_t i = layer+1; i <= 1; ++i)
1356 {
1357 if (get_qr(qr_OLD_BRIDGE_COMBOS))
1358 {
1359 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,i)) return cNONE;
1360 }
1361 else
1362 {
1363 if (combobuf[MAPCOMBO2(i,x,y)].type == cBRIDGE && _effectflag_layer(x,y,i)) return cNONE;
1364 }
1365 }
1366 }
1367 if(layer==-1) return COMBOTYPE(x,y);
1368
1369 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1370 if (!rpos_handle.scr->is_valid()) return 0;
1371
1372 return rpos_handle.ctype();
1373 }
1374
1375 // Returns the flag for the combo at the given position.
1376 // This is also known as an "inherent flag".
1377 97151985 int32_t MAPCOMBOFLAG2(int32_t layer,int32_t x,int32_t y)
1378 {
1379 DCHECK_LAYER_NEG1_INDEX(layer);
1380
2/2
✓ Branch 0 taken 288 times.
✓ Branch 1 taken 97151697 times.
97151985 if (!is_in_world_bounds(x, y))
1381 288 return 0;
1382
2/2
✓ Branch 0 taken 81255084 times.
✓ Branch 1 taken 15896613 times.
97151697 if (layer == -1) return MAPCOMBOFLAG(x, y);
1383
1384 81255084 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, layer + 1);
1385
2/2
✓ Branch 0 taken 63016952 times.
✓ Branch 1 taken 18238132 times.
81255084 if (!rpos_handle.scr->is_valid()) return 0;
1386
1387 18238132 return rpos_handle.cflag();
1388 97151985 }
1389
1390 11626947 bool HASFLAG(int32_t flag, int32_t layer, rpos_t rpos)
1391 {
1392 DCHECK_LAYER_ZERO_INDEX(layer);
1393 11626947 auto rpos_handle = get_rpos_handle(rpos, layer);
1394
2/2
✓ Branch 0 taken 6436552 times.
✓ Branch 1 taken 5190395 times.
11626947 if (!rpos_handle.scr->is_valid()) return false;
1395
2/2
✓ Branch 0 taken 4565 times.
✓ Branch 1 taken 5185830 times.
5190395 if (rpos_handle.sflag() == flag) return true;
1396
2/2
✓ Branch 0 taken 37705 times.
✓ Branch 1 taken 5148125 times.
5185830 if (rpos_handle.cflag() == flag) return true;
1397 5148125 return false;
1398 11626947 }
1399
1400 1697077 bool HASFLAG_ANY(int32_t flag, rpos_t rpos)
1401 {
1402 DCHECK(is_valid_rpos(rpos));
1403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1697077 times.
1697077 if (rpos > region_max_rpos) return false;
1404
1405
2/2
✓ Branch 0 taken 11626947 times.
✓ Branch 1 taken 1654807 times.
13281754 for(auto q = 0; q < 7; ++q)
1406 {
1407
2/2
✓ Branch 0 taken 42270 times.
✓ Branch 1 taken 11584677 times.
11626947 if(HASFLAG(flag, q, rpos))
1408 42270 return true;
1409 11584677 }
1410 1654807 return false;
1411 1697077 }
1412
1413 const char *screenstate_string[32] =
1414 {
1415 "Door Up", "Door Down", "Door Left", "Door Right", "Item", "Special Item", "Some Enemies Never Return",
1416 "Temporary No Return", "Lock Blocks", "Boss Lock Blocks", "Chests", "Locked Chests",
1417 "Boss Locked Chests", "Secrets", "Visited", "Light Beams",
1418 "All Enemies Don't Return", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1419 "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>", "<Unused>",
1420 };
1421
1422 34860 void eventlog_mapflags()
1423 {
1424 34860 std::ostringstream oss;
1425
1426 34860 int mi = mapind(cur_map, home_screen);
1427
1/2
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
34860 dword g = game->maps[mi];
1428
1429
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 34860 times.
✗ Branch 3 not taken.
34860 oss << fmt::format("Screen ({}, {:02X})", cur_map+1, home_screen);
1430
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 20346 times.
34860 if(g) // Main States
1431 {
1432 static const int order[] =
1433 {
1434 mSECRET, mITEM, mSPECIALITEM, mLOCKBLOCK, mBOSSLOCKBLOCK,
1435 mCHEST, mLOCKEDCHEST, mBOSSCHEST,
1436 mDOOR_UP, mDOOR_DOWN, mDOOR_LEFT, mDOOR_RIGHT,
1437 mNEVERRET, mTMPNORET, mLIGHTBEAM, mNO_ENEMIES_RETURN
1438 };
1439
1440
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << " [";
1441 14514 bool comma = false;
1442
2/2
✓ Branch 0 taken 14514 times.
✓ Branch 1 taken 232224 times.
246738 for(int fl : order)
1443 {
1444
2/2
✓ Branch 0 taken 8979 times.
✓ Branch 1 taken 223245 times.
232224 if(!(g&fl))
1445 223245 continue;
1446 8979 byte ind = byte(log2(double(fl)));
1447
2/2
✓ Branch 0 taken 1922 times.
✓ Branch 1 taken 7057 times.
8979 if(comma)
1448
1/2
✓ Branch 0 taken 1922 times.
✗ Branch 1 not taken.
1922 oss << ", ";
1449
1/2
✓ Branch 0 taken 8979 times.
✗ Branch 1 not taken.
8979 oss << screenstate_string[ind];
1450 8979 comma = true;
1451 }
1452
1/2
✓ Branch 0 taken 14514 times.
✗ Branch 1 not taken.
14514 oss << "]";
1453 14514 }
1454
3/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 34822 times.
34860 if(game->xstates[mi]) // ExStates
1455 {
1456
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << " Ex[";
1457 38 bool comma = false;
1458
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1216 times.
1254 for(byte fl = 0; fl < 32; ++fl)
1459 {
1460
3/4
✓ Branch 0 taken 1216 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44 times.
✓ Branch 3 taken 1172 times.
1216 if(game->xstates[mi] & (1<<fl))
1461 {
1462
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 38 times.
44 if(comma)
1463
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 oss << ", ";
1464
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
44 oss << int(fl);
1465 44 comma = true;
1466 44 }
1467 1216 }
1468
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 oss << "]";
1469 38 }
1470 { // ExDoors
1471
2/2
✓ Branch 0 taken 34860 times.
✓ Branch 1 taken 139440 times.
174300 for(int q = 0; q < 4; ++q)
1472 {
1473 139440 bool comma = false;
1474
3/4
✓ Branch 0 taken 139440 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 139438 times.
✓ Branch 3 taken 2 times.
139440 if(auto v = game->xdoors[mi][q])
1475 {
1476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(comma)
1477 oss << ",";
1478
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 else oss << " ExDoor";
1479
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 oss << "[" << dirstr[q];
1480
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 for(int fl = 0; fl < 8; ++fl)
1481
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 3 times.
19 if(v & (1<<fl))
1482
2/4
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
3 oss << " " << int(fl);
1483
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 oss << "]";
1484 2 comma = true;
1485 2 }
1486 139440 }
1487 }
1488
2/4
✓ Branch 0 taken 34860 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34860 times.
34860 Z_eventlog("%s\n", oss.str().c_str());
1489 34860 }
1490
1491 // set specific flag
1492 5616 void setmapflag(mapscr* scr, uint32_t flag)
1493 {
1494
2/2
✓ Branch 0 taken 5603 times.
✓ Branch 1 taken 13 times.
5616 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1495 5616 int mi = mapind(cur_map, scr->screen);
1496 5616 setmapflag_mi(scr, mi, flag);
1497 5616 }
1498 57 void setmapflag_homescr(uint32_t flag)
1499 {
1500 57 int mi = mapind(cur_map, home_screen);
1501 57 setmapflag_mi(origin_scr, mi, flag);
1502 57 }
1503 2023 void setmapflag_mi(int32_t mi, uint32_t flag)
1504 {
1505 2023 byte cscr = mi&((1<<7)-1);
1506 2023 byte cmap = (mi>>7);
1507 2023 mapscr* scr = origin_scr;
1508
2/2
✓ Branch 0 taken 834 times.
✓ Branch 1 taken 1189 times.
2023 if (is_in_current_region(cmap, cscr))
1509 1189 scr = get_scr(cmap, cscr);
1510
1511 2023 setmapflag_mi(scr, mi, flag);
1512 2023 }
1513
1514 8478 static void log_state_change(int map, int screen, std::string action)
1515 {
1516
6/6
✓ Branch 0 taken 1913 times.
✓ Branch 1 taken 6565 times.
✓ Branch 2 taken 996 times.
✓ Branch 3 taken 917 times.
✓ Branch 4 taken 352 times.
✓ Branch 5 taken 644 times.
8478 if (is_in_current_region(map, screen) || (map == cur_map && screen == home_screen))
1517 6917 Z_eventlog("[Map %d, Screen %02X (current)] %s\n", map + 1, screen, action.c_str());
1518 else
1519 1561 Z_eventlog("[Map %d, Screen %02X] %s\n", map + 1, screen, action.c_str());
1520 8478 }
1521
1522 7696 void setmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag)
1523 {
1524 7696 byte cscr = mi&((1<<7)-1);
1525 7696 byte cmap = (mi>>7);
1526
1527 7696 double temp=log2((double)flag);
1528
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1529 7696 const char* replay_state_string = state_string;
1530
2/2
✓ Branch 0 taken 7176 times.
✓ Branch 1 taken 520 times.
7696 if(temp == 6) replay_state_string = "No Return";
1531
1532
3/4
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1552 times.
✓ Branch 3 taken 6144 times.
7696 if (replay_is_active() && !(game->maps[mi] & flag))
1533
1/2
✓ Branch 0 taken 6144 times.
✗ Branch 1 not taken.
6144 replay_step_comment(fmt::format("map {} scr {} flag {}", cmap, cscr, replay_state_string));
1534 7696 game->maps[mi] |= flag;
1535
1/2
✓ Branch 0 taken 7696 times.
✗ Branch 1 not taken.
7696 log_state_change(cmap, cscr, fmt::format("State set: {}", state_string));
1536
1537
2/2
✓ Branch 0 taken 2507 times.
✓ Branch 1 taken 5189 times.
7696 if((scr->nocarry&flag)!=flag)
1538 {
1539 5189 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1540 5189 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1541
1542 5189 std::vector<int32_t> done;
1543
2/2
✓ Branch 0 taken 5094 times.
✓ Branch 1 taken 95 times.
5189 bool looped = (nmap==cmap+1 && nscr==cscr);
1544
1545
6/6
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 5147 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 364 times.
✓ Branch 4 taken 364 times.
✓ Branch 5 taken 5189 times.
5553 while((nmap!=0) && !looped && !(nscr>=128))
1546 {
1547
3/4
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 171 times.
✓ Branch 3 taken 193 times.
364 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1548 {
1549
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 log_state_change(nmap, nscr, "State change carried over");
1550
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 if (replay_is_active())
1551
2/4
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 193 times.
✗ Branch 3 not taken.
193 replay_step_comment(fmt::format("map {} scr {} flag {} carry", nmap, nscr, replay_state_string));
1552
1/2
✓ Branch 0 taken 193 times.
✗ Branch 1 not taken.
193 game->maps[((nmap-1)<<7)+nscr] |= flag;
1553 193 }
1554
1555 364 cmap=nmap;
1556 364 cscr=nscr;
1557 364 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1558 364 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1559
1560
2/2
✓ Branch 0 taken 889 times.
✓ Branch 1 taken 364 times.
1253 for(auto it = done.begin(); it != done.end(); it++)
1561 {
1562
2/2
✓ Branch 0 taken 847 times.
✓ Branch 1 taken 42 times.
889 if(*it == ((nmap-1)<<7)+nscr)
1563 42 looped = true;
1564 889 }
1565
1566
1/2
✓ Branch 0 taken 364 times.
✗ Branch 1 not taken.
364 done.push_back(((nmap-1)<<7)+nscr);
1567 }
1568 5189 }
1569 7696 }
1570
1571 void unsetmapflag_home(uint32_t flag, bool anyflag)
1572 {
1573 int mi = mapind(cur_map, home_screen);
1574 unsetmapflag_mi(origin_scr, mi, flag, anyflag);
1575 }
1576
1577 void unsetmapflag(mapscr* scr, uint32_t flag, bool anyflag)
1578 {
1579 if (scr->screen >= 0x80) scr = special_warp_return_scr;
1580 int mi = mapind(cur_map, scr->screen);
1581 unsetmapflag_mi(scr, mi, flag, anyflag);
1582 }
1583
1584 471 void unsetmapflag_mi(int32_t mi, uint32_t flag, bool anyflag)
1585 {
1586 471 byte cscr = mi&((1<<7)-1);
1587 471 byte cmap = (mi>>7);
1588 471 mapscr* scr = origin_scr;
1589
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if (is_in_current_region(cmap, cscr))
1590 11 scr = get_scr(cmap, cscr);
1591
1592 471 unsetmapflag_mi(scr, mi, flag, anyflag);
1593 471 }
1594
1595 471 void unsetmapflag_mi(mapscr* scr, int32_t mi, uint32_t flag, bool anyflag)
1596 {
1597 471 byte cscr = mi&((1<<7)-1);
1598 471 byte cmap = (mi>>7);
1599
1600
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 11 times.
471 if(anyflag)
1601 460 game->maps[mi] &= ~flag;
1602
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 11 times.
11 else if(flag==mITEM || flag==mSPECIALITEM)
1603 {
1604 if(!(scr->flags4&fNOITEMRESET))
1605 game->maps[mi] &= ~flag;
1606 }
1607 11 else game->maps[mi] &= ~flag;
1608
1609 471 double temp=log2((double)flag);
1610
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 const char* state_string = flag>0 ? screenstate_string[(int32_t)temp] : "<Unknown>";
1611
1/2
✓ Branch 0 taken 471 times.
✗ Branch 1 not taken.
471 log_state_change(cmap, cscr, fmt::format("State unset: {}", state_string));
1612
1613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 471 times.
471 if((scr->nocarry&flag)!=flag)
1614 {
1615 471 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1616 471 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1617
1618 471 std::vector<int32_t> done;
1619
2/2
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 5 times.
471 bool looped = (nmap==cmap+1 && nscr==cscr);
1620
1621
6/6
✓ Branch 0 taken 90 times.
✓ Branch 1 taken 465 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 84 times.
✓ Branch 4 taken 84 times.
✓ Branch 5 taken 471 times.
555 while((nmap!=0) && !looped && !(nscr>=128))
1622 {
1623
3/4
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 72 times.
84 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1624 {
1625
2/4
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
72 log_state_change(nmap, nscr, "State change carried over");
1626
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 game->maps[((nmap-1)<<7)+nscr] &= ~flag;
1627 72 }
1628
1629 84 cmap=nmap;
1630 84 cscr=nscr;
1631 84 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1632 84 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1633
1634
2/2
✓ Branch 0 taken 84 times.
✓ Branch 1 taken 546 times.
630 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1635 {
1636
2/2
✓ Branch 0 taken 540 times.
✓ Branch 1 taken 6 times.
546 if(*it == ((nmap-1)<<7)+nscr)
1637 6 looped = true;
1638 546 }
1639
1640
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 done.push_back(((nmap-1)<<7)+nscr);
1641 }
1642 471 }
1643 471 }
1644
1645 50173955 bool getmapflag(int32_t screen, uint32_t flag)
1646 {
1647
2/2
✓ Branch 0 taken 1345925 times.
✓ Branch 1 taken 48828030 times.
50173955 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1648 50173955 return (game->maps[mi] & flag) != 0;
1649 }
1650 6228660 bool getmapflag(mapscr* scr, uint32_t flag)
1651 {
1652 6228660 return getmapflag(scr->screen, flag);
1653 }
1654
1655 60 void setxmapflag(int32_t screen, uint32_t flag)
1656 {
1657
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 60 times.
60 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1658 60 setxmapflag_mi(mi, flag);
1659 60 }
1660 62 void setxmapflag_mi(int32_t mi, uint32_t flag)
1661 {
1662
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 41 times.
62 if(game->xstates[mi] & flag) return;
1663 41 byte cscr = mi&((1<<7)-1);
1664 41 byte cmap = (mi>>7);
1665
1666 41 byte temp=(byte)log2((double)flag);
1667
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 log_state_change(cmap, cscr, fmt::format("ExtraState set: {}", temp));
1668
1669 41 game->xstates[mi] |= flag;
1670
1671 41 mapscr* scr = origin_scr;
1672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41 times.
41 if (is_in_current_region(cmap, cscr))
1673 41 scr = get_scr(cmap, cscr);
1674
1675
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 if((scr->exstate_carry&flag)==flag)
1676 {
1677 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1678 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1679
1680 std::vector<int32_t> done;
1681 bool looped = (nmap==cmap+1 && nscr==cscr);
1682
1683 while((nmap!=0) && !looped && !(nscr>=128))
1684 {
1685 if(!(game->maps[((nmap-1)<<7)+nscr] & flag))
1686 {
1687 log_state_change(nmap, nscr, "ExState change carried over");
1688 if (replay_is_active())
1689 replay_step_comment(fmt::format("map {} scr {} exstate {} carry", nmap, nscr, temp));
1690 game->xstates[((nmap-1)<<7)+nscr] |= flag;
1691 }
1692
1693 cmap=nmap;
1694 cscr=nscr;
1695 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1696 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1697
1698 for(auto it = done.begin(); it != done.end(); it++)
1699 {
1700 if(*it == ((nmap-1)<<7)+nscr)
1701 looped = true;
1702 }
1703
1704 done.push_back(((nmap-1)<<7)+nscr);
1705 }
1706 }
1707 62 }
1708 2 void unsetxmapflag(int32_t screen, uint32_t flag)
1709 {
1710
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1711 2 unsetxmapflag_mi(mi, flag);
1712 2 }
1713 2 void unsetxmapflag_mi(int32_t mi, uint32_t flag)
1714 {
1715
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if(!(game->xstates[mi] & flag)) return;
1716 1 byte cscr = mi&((1<<7)-1);
1717 1 byte cmap = (mi>>7);
1718 1 byte temp=(byte)log2((double)flag);
1719
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 log_state_change(cmap, cscr, fmt::format("ExtraState unset: {}", temp));
1720 1 game->xstates[mi] &= ~flag;
1721
1722 1 mapscr* scr = origin_scr;
1723
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (is_in_current_region(cmap, cscr))
1724 1 scr = get_scr(cmap, cscr);
1725
1726
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if((scr->exstate_carry&flag)==flag)
1727 {
1728 byte nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
1729 byte nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
1730
1731 std::vector<int32_t> done;
1732 bool looped = (nmap==cmap+1 && nscr==cscr);
1733
1734 while((nmap!=0) && !looped && !(nscr>=128))
1735 {
1736 if(game->maps[((nmap-1)<<7)+nscr] & flag)
1737 {
1738 log_state_change(nmap, nscr, "ExState change carried over");
1739 game->xstates[((nmap-1)<<7)+nscr] &= ~flag;
1740 }
1741
1742 cmap=nmap;
1743 cscr=nscr;
1744 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
1745 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
1746
1747 for(std::vector<int32_t>::iterator it = done.begin(); it != done.end(); it++)
1748 {
1749 if(*it == ((nmap-1)<<7)+nscr)
1750 looped = true;
1751 }
1752
1753 done.push_back(((nmap-1)<<7)+nscr);
1754 }
1755 }
1756 2 }
1757 34 bool getxmapflag(int32_t screen, uint32_t flag)
1758 {
1759
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
1760 34 return getxmapflag_mi(mi, flag);
1761 }
1762 471496240 bool getxmapflag_mi(int32_t mi, uint32_t flag)
1763 {
1764 471496240 return (game->xstates[mi] & flag) != 0;
1765 }
1766
1767 4 void setxdoor_mi(uint mi, uint dir, uint ind, bool state)
1768 {
1769
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
4 if(mi > game->xdoors.size() || dir > 3 || ind > 8)
1770 return;
1771
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if(!(game->xdoors[mi][dir] & (1<<ind)) == !state)
1772 return;
1773
1774
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 SETFLAG(game->xdoors[mi][dir], 1<<ind, state);
1775
1776 4 int cscr = mi % MAPSCRSNORMAL;
1777 4 int cmap = mi / MAPSCRSNORMAL;
1778
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (state)
1779
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] set", dirstr[dir], ind));
1780 else
1781 log_state_change(cmap, cscr, fmt::format("ExDoor[{}][{}] unset", dirstr[dir], ind));
1782 4 }
1783 471496201 bool getxdoor_mi(uint mi, uint dir, uint ind)
1784 {
1785
3/6
✓ Branch 0 taken 471496201 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 471496201 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 471496201 times.
471496201 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1786 return false;
1787 471496201 return (game->xdoors[mi][dir] & (1<<ind));
1788 471496201 }
1789 9 bool getxdoor(int32_t screen, uint dir, uint ind)
1790 {
1791 9 int mi = mapind(cur_map, screen);
1792 9 return getxdoor_mi(mi,dir,ind);
1793 }
1794
1795 401 void set_doorstate_mi(uint mi, uint dir)
1796 {
1797
1/2
✓ Branch 0 taken 401 times.
✗ Branch 1 not taken.
401 if(dir >= 4)
1798 return;
1799 401 setmapflag_mi(mi, mDOOR_UP << dir);
1800
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 400 times.
401 if(auto di = nextscr_mi(mi, dir))
1801 400 setmapflag_mi(*di, mDOOR_UP << oppositeDir[dir]);
1802 401 }
1803 401 void set_doorstate(uint screen, uint dir)
1804 {
1805 401 int mi = mapind(cur_map, screen);
1806 401 set_doorstate_mi(mi, dir);
1807 401 }
1808
1809 2 void set_xdoorstate_mi(uint mi, uint dir, uint ind, bool state)
1810 {
1811
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if(mi >= game->xdoors.size() || dir >= 4 || ind >= 8)
1812 return;
1813 2 setxdoor_mi(mi, dir, ind, state);
1814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if(auto di = nextscr_mi(mi, dir))
1815 2 setxdoor_mi(*di, oppositeDir[dir], ind, state);
1816 2 }
1817
1818 2 void set_xdoorstate(int32_t screen,uint dir, uint ind, bool state)
1819 {
1820 2 int mi = mapind(cur_map, screen);
1821 2 set_xdoorstate_mi(mi, dir, ind, state);
1822 2 }
1823
1824 57 int32_t WARPCODE(int32_t dmap,int32_t screen,int32_t dw)
1825 // returns: -1 = not a warp screen
1826 // 0+ = warp screen code ( high byte=dmap, low byte=scr )
1827 {
1828 57 const mapscr *scr = get_canonical_scr(DMaps[dmap].map, screen);
1829
1830
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(scr->room!=rWARP)
1831 return -1;
1832
1833 57 int32_t ring=scr->catchall;
1834 57 int32_t size=QMisc.warp[ring].size;
1835
1836
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 if(size==0)
1837 return -2;
1838
1839 57 int32_t index=-1;
1840
1841
2/2
✓ Branch 0 taken 289 times.
✓ Branch 1 taken 57 times.
346 for(int32_t i=0; i<size; i++)
1842
6/6
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 59 times.
✓ Branch 2 taken 173 times.
✓ Branch 3 taken 57 times.
✓ Branch 4 taken 173 times.
✓ Branch 5 taken 57 times.
289 if(dmap==QMisc.warp[ring].dmap[i] && screen==
1843 346 (QMisc.warp[ring].scr[i] + DMaps[dmap].xoff))
1844 57 index=i;
1845
1846
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 57 times.
57 if(index==-1)
1847 return -3;
1848
1849 57 index = (index+dw)%size;
1850 57 return (QMisc.warp[ring].dmap[index] << 8) + QMisc.warp[ring].scr[index];
1851 57 }
1852
1853 14779694 void update_combo_cycling()
1854 {
1855 14779694 auto& combo_cache = combo_caches::can_cycle;
1856
1857 static int32_t newdata[176];
1858 static int32_t newcset[176];
1859 static bool initialized=false;
1860
1861 // Just a simple bit of optimization
1862
2/2
✓ Branch 0 taken 14779383 times.
✓ Branch 1 taken 311 times.
14779694 if(!initialized)
1863 {
1864
2/2
✓ Branch 0 taken 54736 times.
✓ Branch 1 taken 311 times.
55047 for(int32_t i=0; i<176; i++)
1865 {
1866 54736 newdata[i]=-1;
1867 54736 newcset[i]=-1;
1868 54736 }
1869
1870 311 initialized=true;
1871 311 }
1872
1873 14779694 std::set<uint16_t> restartanim;
1874
1875
1/2
✓ Branch 0 taken 14779694 times.
✗ Branch 1 not taken.
29948756 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
1876 15169062 int screen = scr->screen;
1877 int32_t x;
1878
1879
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1880 {
1881 2669754912 x=scr->data[i];
1882 2669754912 auto& mini_cmb = combo_cache.minis[x];
1883
2/2
✓ Branch 0 taken 3273932 times.
✓ Branch 1 taken 2666480980 times.
2669754912 if (!mini_cmb.can_cycle)
1884 2666480980 continue;
1885
1886 3273932 newcombo const& cmb = combobuf[x];
1887
1888 //time to restart
1889
4/4
✓ Branch 0 taken 902694 times.
✓ Branch 1 taken 2371238 times.
✓ Branch 2 taken 474434 times.
✓ Branch 3 taken 428260 times.
3273932 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1890 {
1891 428260 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428260 times.
428260 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1893 428260 newdata[i] = c;
1894
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(!(cmb.animflags & AF_CYCLENOCSET))
1895
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 428240 times.
428240 newcset[i] = cycle_under ? scr->undercset : cmb.nextcset;
1896
1897
2/2
✓ Branch 0 taken 427216 times.
✓ Branch 1 taken 1044 times.
428260 if(combobuf[c].animflags & AF_CYCLE)
1898 {
1899 1044 restartanim.insert(c);
1900 1044 }
1901 428260 }
1902 3273932 }
1903
1904 15169062 int rpos_base = (int)POS_TO_RPOS(0, region_scr_x, region_scr_y);
1905
2/2
✓ Branch 0 taken 2669754912 times.
✓ Branch 1 taken 15169062 times.
2684923974 for(int32_t i=0; i<176; i++)
1906 {
1907
2/2
✓ Branch 0 taken 428260 times.
✓ Branch 1 taken 2669326652 times.
2669754912 if(newdata[i]==-1)
1908 2669326652 continue;
1909
1910 428260 rpos_t rpos = (rpos_t)(rpos_base + i);
1911 428260 rpos_handle_t rpos_handle = {scr, screen, 0, rpos, i};
1912 428260 screen_combo_modify_preroutine(rpos_handle);
1913 428260 scr->data[i]=newdata[i];
1914
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 428240 times.
428260 if(newcset[i]>-1)
1915 428240 scr->cset[i]=newcset[i];
1916 428260 screen_combo_modify_postroutine(rpos_handle);
1917
1918 428260 newdata[i]=-1;
1919 428260 newcset[i]=-1;
1920 428260 }
1921
1922 15169062 word c = scr->numFFC();
1923
2/2
✓ Branch 0 taken 15169062 times.
✓ Branch 1 taken 453640163 times.
468809225 for(word i=0; i<c; i++)
1924 {
1925 453640163 ffcdata& ffc = scr->ffcs[i];
1926 453640163 auto& mini_cmb = combo_cache.minis[ffc.data];
1927
2/2
✓ Branch 0 taken 4173 times.
✓ Branch 1 taken 453635990 times.
453640163 if (!mini_cmb.can_cycle)
1928 453635990 continue;
1929
1930 4173 newcombo const& cmb = combobuf[ffc.data];
1931
1932 //time to restart
1933
4/4
✓ Branch 0 taken 611 times.
✓ Branch 1 taken 3562 times.
✓ Branch 2 taken 503 times.
✓ Branch 3 taken 108 times.
4173 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1934 {
1935 108 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 auto c = cycle_under ? scr->undercombo : cmb.nextcombo;
1937 108 zc_ffc_set(ffc, c);
1938
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 if(!(cmb.animflags & AF_CYCLENOCSET))
1939
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 108 times.
108 ffc.cset = cycle_under ? scr->undercset : cmb.nextcset;
1940
1941
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 60 times.
108 if(combobuf[ffc.data].animflags & AF_CYCLE)
1942 {
1943 60 restartanim.insert(ffc.data);
1944 60 }
1945 108 }
1946 4173 }
1947
1948
2/2
✓ Branch 0 taken 8418399 times.
✓ Branch 1 taken 6750663 times.
15169062 if(get_qr(qr_CMBCYCLELAYERS))
1949 {
1950
2/2
✓ Branch 0 taken 40503978 times.
✓ Branch 1 taken 6750663 times.
47254641 for(int32_t j=1; j<=6; j++)
1951 {
1952 40503978 mapscr* layer_scr = get_scr_layer_valid(screen, j);
1953
2/2
✓ Branch 0 taken 10894345 times.
✓ Branch 1 taken 29609633 times.
40503978 if (!layer_scr)
1954 29609633 continue;
1955
1956
2/2
✓ Branch 0 taken 1917404720 times.
✓ Branch 1 taken 10894345 times.
1928299065 for(int32_t i=0; i<176; i++)
1957 {
1958 1917404720 x=layer_scr->data[i];
1959 1917404720 auto& mini_cmb = combo_cache.minis[x];
1960
2/2
✓ Branch 0 taken 2230074 times.
✓ Branch 1 taken 1915174646 times.
1917404720 if (!mini_cmb.can_cycle)
1961 1915174646 continue;
1962
1963 2230074 newcombo const& cmb = combobuf[x];
1964
1965 //time to restart
1966
4/4
✓ Branch 0 taken 48416 times.
✓ Branch 1 taken 2181658 times.
✓ Branch 2 taken 37483 times.
✓ Branch 3 taken 10933 times.
2230074 if ((cmb.aclk>=cmb.speed) && combocheck(cmb))
1967 {
1968 10933 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
1969
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 auto c = cycle_under ? layer_scr->undercombo : cmb.nextcombo;
1970 10933 newdata[i] = c;
1971
2/2
✓ Branch 0 taken 69 times.
✓ Branch 1 taken 10864 times.
10933 if(!(cmb.animflags & AF_CYCLENOCSET))
1972
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10864 times.
10864 newcset[i] = cycle_under ? layer_scr->undercset : cmb.nextcset;
1973 69 else newcset[i] = layer_scr->cset[i];
1974
1975
2/2
✓ Branch 0 taken 950 times.
✓ Branch 1 taken 9983 times.
10933 if(combobuf[c].animflags & AF_CYCLE)
1976 {
1977 9983 restartanim.insert(c);
1978 9983 }
1979 10933 }
1980 2230074 }
1981
1982
2/2
✓ Branch 0 taken 1917404720 times.
✓ Branch 1 taken 10894345 times.
1928299065 for (int32_t i=0; i<176; i++)
1983 {
1984
2/2
✓ Branch 0 taken 1917393787 times.
✓ Branch 1 taken 10933 times.
1917404720 if(newdata[i]!=-1)
1985 {
1986 10933 layer_scr->data[i]=newdata[i];
1987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10933 times.
10933 if(newcset[i]>-1)
1988 10933 layer_scr->cset[i]=newcset[i];
1989 10933 newdata[i]=-1;
1990 10933 newcset[i]=-1;
1991 10933 }
1992 1917404720 }
1993 10894345 }
1994 6750663 }
1995 15169062 });
1996
1997
2/2
✓ Branch 0 taken 14779694 times.
✓ Branch 1 taken 2661 times.
14782355 for (auto i : restartanim)
1998 {
1999 2661 combobuf[i].tile = combobuf[i].o_tile;
2000 2661 combobuf[i].cur_frame=0;
2001 2661 combobuf[i].aclk = 0;
2002
1/2
✓ Branch 0 taken 2661 times.
✗ Branch 1 not taken.
2661 combo_caches::drawing.refresh(i);
2003 }
2004 14779694 }
2005
2006 1209944910 bool iswater_type(int32_t type)
2007 {
2008 // return type==cOLD_WATER || type==cSWIMWARP || type==cDIVEWARP || type==cDIVEWARPB || type==cDIVEWARPC || type==cDIVEWARPD || type==cSWIMWARPB || type==cSWIMWARPC || type==cSWIMWARPD;
2009 1209944910 return (combo_class_buf[type].water!=0);
2010 }
2011
2012 bool iswater(int32_t combo)
2013 {
2014 return iswater_type(combobuf[combo].type) && !DRIEDLAKE;
2015 }
2016 1135408 int32_t iswaterexzq(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck)
2017 {
2018 1135408 return iswaterex(combo, map, screen, layer, x, y, secrets, fullcheck, LayerCheck);
2019 }
2020
2021 // (x, y) are world coordinates
2022 58744386 int32_t iswaterex_z3(int32_t combo, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2023 {
2024
8/8
✓ Branch 0 taken 58698235 times.
✓ Branch 1 taken 46151 times.
✓ Branch 2 taken 58657903 times.
✓ Branch 3 taken 40332 times.
✓ Branch 4 taken 58591157 times.
✓ Branch 5 taken 66746 times.
✓ Branch 6 taken 59577 times.
✓ Branch 7 taken 58531580 times.
58744386 if (x<0 || x>=world_w || y<0 || y>=world_h)
2025 212806 return false;
2026
2027 58531580 return iswaterex(combo, cur_map, cur_screen, layer, x, y, secrets, fullcheck, LayerCheck, ShallowCheck, hero, out_handle);
2028 58744386 }
2029
2030 97204252 int32_t iswaterex(int32_t combo, int32_t map, int32_t screen, int32_t layer, int32_t x, int32_t y, bool secrets, bool fullcheck, bool LayerCheck, bool ShallowCheck, bool hero, optional<combined_handle_t>* out_handle)
2031 {
2032 DCHECK_LAYER_NEG1_INDEX(layer);
2033 //Honestly, fullcheck is kinda useless... I made this function back when I thought it was checking the entire combo and not just a glorified x/y value.
2034 //Fullcheck makes no sense to ever be on, but hey I guess it's here in case you ever need it...
2035
2036 //Oh hey, Zoras might actually need it. Nevermind, this had a use!
2037
2/2
✓ Branch 0 taken 57354791 times.
✓ Branch 1 taken 39849461 times.
97204252 if (get_qr(qr_SMARTER_WATER))
2038 {
2039
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 57354791 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
57354791 if (DRIEDLAKE) return 0;
2040
5/6
✓ Branch 0 taken 19559904 times.
✓ Branch 1 taken 37794887 times.
✓ Branch 2 taken 6518562 times.
✓ Branch 3 taken 13041342 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6518562 times.
57354791 if (LayerCheck && (get_qr(qr_WATER_ON_LAYER_1) || get_qr(qr_WATER_ON_LAYER_2))) //LayerCheck is a bit dumber, but it lets me add this QR without having to replace all calls, again.
2041 {
2042
2/2
✓ Branch 0 taken 37777366 times.
✓ Branch 1 taken 12368012 times.
50145378 for (int32_t m = layer; m <= 1; m++)
2043 {
2044
5/6
✓ Branch 0 taken 24736024 times.
✓ Branch 1 taken 13041342 times.
✓ Branch 2 taken 12368012 times.
✓ Branch 3 taken 12368012 times.
✓ Branch 4 taken 12368012 times.
✗ Branch 5 not taken.
50145378 if (m < 0 || m == 0 && get_qr(qr_WATER_ON_LAYER_1)
2045
1/2
✓ Branch 0 taken 12368012 times.
✗ Branch 1 not taken.
24736024 || m == 1 && get_qr(qr_WATER_ON_LAYER_2))
2046 {
2047 37777366 int32_t checkwater = iswaterex(combo, map, screen, m, x, y, secrets, fullcheck, false, ShallowCheck);
2048
2/2
✓ Branch 0 taken 37104036 times.
✓ Branch 1 taken 673330 times.
37777366 if (checkwater > 0)
2049 {
2050
2/2
✓ Branch 0 taken 673272 times.
✓ Branch 1 taken 58 times.
673330 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, m+1);
2051 673330 return checkwater;
2052 }
2053 37104036 }
2054 37104036 }
2055 12368012 return 0;
2056 }
2057 else
2058 {
2059
2/2
✓ Branch 0 taken 44328122 times.
✓ Branch 1 taken 42139295 times.
86467417 for(int32_t i=(fullcheck?3:0); i>=0; i--)
2060 {
2061 44328122 int32_t tx2=((i&2)<<2)+x;
2062 44328122 int32_t ty2=((i&1)<<3)+y;
2063 44328122 int32_t b = i; //Originally b was not needed and I read off i, but then I added the boolean for fullcheck.
2064 //In which case it's just easier to change b if fullcheck is false instead of changing i and potentially screwing up the for loop.
2065
2/2
✓ Branch 0 taken 21673 times.
✓ Branch 1 taken 44306449 times.
44328122 if (!fullcheck)
2066 {
2067 44306449 tx2 = x;
2068 44306449 ty2 = y;
2069
2/2
✓ Branch 0 taken 24875581 times.
✓ Branch 1 taken 19430868 times.
44306449 if(tx2&8) b+=2;
2070
2/2
✓ Branch 0 taken 20524110 times.
✓ Branch 1 taken 23782339 times.
44306449 if(ty2&8) b+=1;
2071 44306449 }
2072
2/2
✓ Branch 0 taken 94774118 times.
✓ Branch 1 taken 43483889 times.
138258007 for (int32_t m = layer; m <= 1; m++)
2073 {
2074 94774118 newcombo const& cmb = combobuf[MAPCOMBO3(map, screen, m,tx2,ty2, true)];
2075
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 77038391 times.
94774118 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2076 {
2077
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 17735727 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17735727 if (cmb.type == cBRIDGE && !(cmb.walk&(1<<b)))
2078 {
2079 return 0;
2080 }
2081 17735727 }
2082 else
2083 {
2084
4/4
✓ Branch 0 taken 179102 times.
✓ Branch 1 taken 76859289 times.
✓ Branch 2 taken 51152 times.
✓ Branch 3 taken 127950 times.
77038391 if (cmb.type == cBRIDGE && (cmb.walk&(0x10<<b)))
2085 {
2086 127950 return 0;
2087 }
2088 }
2089
2/2
✓ Branch 0 taken 17735727 times.
✓ Branch 1 taken 76910441 times.
94646168 if (get_qr(qr_NO_SOLID_SWIM))
2090 {
2091
8/14
✓ Branch 0 taken 51152 times.
✓ Branch 1 taken 76859289 times.
✓ Branch 2 taken 51152 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 716283 times.
✓ Branch 5 taken 76143006 times.
✓ Branch 6 taken 3461 times.
✓ Branch 7 taken 712822 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 3461 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
76910441 if ((cmb.type != cBRIDGE || (!get_qr(qr_OLD_BRIDGE_COMBOS) && !(cmb.walk&(0x10<<b)))) && (cmb.walk&(1<<b)) && !((cmb.usrflags&cflag4) && cmb.type == cWATER && (cmb.walk&(0x10<<b)) && ShallowCheck))
2092 {
2093 716283 return 0;
2094 }
2095 76194158 }
2096
3/6
✓ Branch 0 taken 320336 times.
✓ Branch 1 taken 93609549 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 320336 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
93929885 if (iswater_type(cmb.type) && (cmb.walk&(1<<b)) && ((cmb.usrflags&cflag3) || (cmb.usrflags&cflag4)
2097 || (hero && current_item(itype_flippers) < cmb.attribytes[0])
2098 || (hero && ((cmb.usrflags&cflag1) && !(itemsbuf[current_item_id(itype_flippers)].flags & item_flag3)))))
2099 {
2100 if (!(ShallowCheck && (cmb.walk&(1<<b)) && (cmb.usrflags&cflag4))) return 0;
2101 }
2102 93929885 }
2103
2104 131346201 auto found_ffc_not_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2105
2/2
✓ Branch 0 taken 87334447 times.
✓ Branch 1 taken 527865 times.
87862312 if (ffcIsAt(ffc_handle, tx2, ty2))
2106 {
2107 527865 auto ty = ffc_handle.ctype();
2108
4/6
✓ Branch 0 taken 527865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144225 times.
✓ Branch 3 taken 383640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 144225 times.
527865 if(!combo_class_buf[ty].water && !(ShallowCheck && ty == cSHALLOWWATER))
2109 527865 return true;
2110 }
2111
2112 87334447 return false;
2113 87862312 });
2114
2/2
✓ Branch 0 taken 42956024 times.
✓ Branch 1 taken 527865 times.
43483889 if (found_ffc_not_water) return 0;
2115
2116
2/2
✓ Branch 0 taken 14673 times.
✓ Branch 1 taken 42941351 times.
42956024 if(!i)
2117 {
2118 127951877 auto found_ffc_water = find_ffc([&](const ffc_handle_t& ffc_handle) {
2119
1/2
✓ Branch 0 taken 85010526 times.
✗ Branch 1 not taken.
85010526 if (ffcIsAt(ffc_handle, tx2, ty2))
2120 {
2121 auto ty = ffc_handle.ctype();
2122 if(combo_class_buf[ty].water || (ShallowCheck && ty == cSHALLOWWATER))
2123 return true;
2124 }
2125
2126 85010526 return false;
2127 85010526 });
2128
1/2
✓ Branch 0 taken 42941351 times.
✗ Branch 1 not taken.
42941351 if (found_ffc_water)
2129 {
2130 if(out_handle) *out_handle = *found_ffc_water;
2131 return found_ffc_water->data();
2132 }
2133 42941351 }
2134
2135 42956024 int32_t checkcombo = MAPCOMBO3(map, screen, layer, tx2, ty2, secrets);
2136
2/2
✓ Branch 0 taken 42911530 times.
✓ Branch 1 taken 44494 times.
42956024 if (!(combobuf[checkcombo].walk&(1<<(b+4)))) return 0;
2137
7/12
✓ Branch 0 taken 42630925 times.
✓ Branch 1 taken 280605 times.
✓ Branch 2 taken 10830561 times.
✓ Branch 3 taken 31800364 times.
✓ Branch 4 taken 10352377 times.
✓ Branch 5 taken 478184 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 10352377 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
42911530 if (iswater_type(combobuf[checkcombo].type)||(ShallowCheck && (combobuf[checkcombo].type == cSHALLOWWATER || (iswater_type(combobuf[checkcombo].type) && (combobuf[checkcombo].walk&(1<<b)) && (combobuf[checkcombo].usrflags&cflag4)))))
2138 {
2139
2/2
✓ Branch 0 taken 1227 times.
✓ Branch 1 taken 757562 times.
758789 if (i == 0)
2140 {
2141
2/2
✓ Branch 0 taken 757553 times.
✓ Branch 1 taken 9 times.
757562 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(tx2, ty2, layer+1);
2142 757562 return checkcombo;
2143 }
2144 1227 }
2145 42153968 }
2146 42139295 return 0;
2147 }
2148 }
2149 else
2150 {
2151 39849461 int32_t b = 0;
2152
2/2
✓ Branch 0 taken 20636412 times.
✓ Branch 1 taken 19213049 times.
39849461 if(x&8) b+=2;
2153
2/2
✓ Branch 0 taken 15456485 times.
✓ Branch 1 taken 24392976 times.
39849461 if(y&8) b+=1;
2154
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (get_qr(qr_NO_SOLID_SWIM))
2155 {
2156 if (combobuf[combo].walk&(1<<b))
2157 {
2158 return 0;
2159 }
2160 }
2161
1/2
✓ Branch 0 taken 39849461 times.
✗ Branch 1 not taken.
39849461 if (!(combobuf[combo].walk&(1<<(b+4)))) return 0;
2162
8/8
✓ Branch 0 taken 38150901 times.
✓ Branch 1 taken 1698560 times.
✓ Branch 2 taken 167945 times.
✓ Branch 3 taken 37982956 times.
✓ Branch 4 taken 2129 times.
✓ Branch 5 taken 1782338 times.
✓ Branch 6 taken 163774 times.
✓ Branch 7 taken 161691 times.
39849461 if((iswater_type(combobuf[combo].type) || (ShallowCheck && combobuf[combo].type == cSHALLOWWATER)) && !DRIEDLAKE)
2163 {
2164
2/2
✓ Branch 0 taken 1943999 times.
✓ Branch 1 taken 30 times.
1944029 if(out_handle) *out_handle = get_rpos_handle_for_world_xy(x, y, 0); //NOTE: This is only correct assuming 'combo' is 'MAPCOMBO(x,y)'
2165 1944029 return combo;
2166 }
2167 38146730 return 0;
2168 }
2169 97445550 }
2170
2171 326 bool isdamage_type(int32_t type)
2172 {
2173
1/2
✓ Branch 0 taken 326 times.
✗ Branch 1 not taken.
326 switch(type)
2174 {
2175 case cDAMAGE1: case cDAMAGE2: case cDAMAGE3: case cDAMAGE4:
2176 case cDAMAGE5: case cDAMAGE6: case cDAMAGE7:
2177 return true;
2178 }
2179 326 return false;
2180 326 }
2181
2182 2569347297 bool ispitfall_type(int32_t type)
2183 {
2184 2569347297 return combo_class_buf[type].pit != 0;
2185 }
2186
2187 2569347297 bool ispitfall(int32_t combo)
2188 {
2189 2569347297 return ispitfall_type(combobuf[combo].type);
2190 }
2191
2192 278127958 bool ispitfall(int32_t x, int32_t y)
2193 {
2194
2/2
✓ Branch 0 taken 1456039 times.
✓ Branch 1 taken 276671919 times.
278127958 if(int32_t c = MAPFFCOMBO(x,y))
2195 {
2196 1456039 return ispitfall(c) ? true : false;
2197 }
2198 276671919 int32_t c = MAPCOMBOL(2,x,y);
2199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 276671919 times.
276671919 if(ispitfall(c)) return true;
2200
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13111152 times.
276671919 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2201 {
2202
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return false;
2203 263560767 }
2204 else
2205 {
2206
3/4
✓ Branch 0 taken 2780 times.
✓ Branch 1 taken 13108372 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2780 times.
13111152 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return false;
2207 }
2208 276669139 c = MAPCOMBOL(1,x,y);
2209
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 276669115 times.
276669139 if(ispitfall(c)) return true;
2210
2211
2/2
✓ Branch 0 taken 263560767 times.
✓ Branch 1 taken 13108348 times.
276669115 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2212 {
2213
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 263560767 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
263560767 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return false;
2214 263560767 }
2215 else
2216 {
2217
4/4
✓ Branch 0 taken 13072 times.
✓ Branch 1 taken 13095276 times.
✓ Branch 2 taken 8777 times.
✓ Branch 3 taken 4295 times.
13108348 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return false;
2218 }
2219 276660338 c = MAPCOMBO(x,y);
2220
2/2
✓ Branch 0 taken 70747 times.
✓ Branch 1 taken 276589591 times.
276660338 if(ispitfall(c)) return true;
2221 276589591 return false;
2222 278127958 }
2223
2224 585542416 int32_t getpitfall(int32_t x, int32_t y) //Return the highest-layer active pit combo at the given position
2225 {
2226
2/2
✓ Branch 0 taken 9281019 times.
✓ Branch 1 taken 576261397 times.
585542416 if(int32_t c = MAPFFCOMBO(x,y))
2227 {
2228
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9281019 times.
9281019 return ispitfall(c) ? c : 0;
2229 }
2230 576261397 int32_t c = MAPCOMBOL(2,x,y);
2231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 576261397 times.
576261397 if(ispitfall(c)) return c;
2232
2233
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43538912 times.
576261397 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2234 {
2235
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1)) return 0;
2236 532722485 }
2237 else
2238 {
2239
3/4
✓ Branch 0 taken 35747 times.
✓ Branch 1 taken 43503165 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 35747 times.
43538912 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1)) return 0;
2240 }
2241 576225650 c = MAPCOMBOL(1,x,y);
2242
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 576225372 times.
576225650 if(ispitfall(c)) return c;
2243
2244
2/2
✓ Branch 0 taken 532722485 times.
✓ Branch 1 taken 43502887 times.
576225372 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2245 {
2246
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 532722485 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
532722485 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0)) return 0;
2247 532722485 }
2248 else
2249 {
2250
4/4
✓ Branch 0 taken 144357 times.
✓ Branch 1 taken 43358530 times.
✓ Branch 2 taken 103729 times.
✓ Branch 3 taken 40628 times.
43502887 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0)) return 0;
2251 }
2252 576121643 c = MAPCOMBO(x,y);
2253
2/2
✓ Branch 0 taken 176844 times.
✓ Branch 1 taken 575944799 times.
576121643 if(ispitfall(c)) return c;
2254 575944799 return 0;
2255 585542416 }
2256 51 optional<combined_handle_t> get_pitfall_handle(int32_t x, int32_t y) //Return the highest-layer active pit combo handle at the given position
2257 {
2258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(int32_t c = MAPFFCOMBO(x,y))
2259 {
2260 return ispitfall(c) ? getFFCAt(x,y) : nullopt;
2261 }
2262 51 int32_t c = MAPCOMBOL(2,x,y);
2263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 2);
2264
2265
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2266 {
2267
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1))
2268 return nullopt;
2269 6 }
2270 else
2271 {
2272
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1))
2273 return nullopt;
2274 }
2275 51 c = MAPCOMBOL(1,x,y);
2276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 1);
2277
2278
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 45 times.
51 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2279 {
2280
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,0))
2281 return nullopt;
2282 6 }
2283 else
2284 {
2285
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 45 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
45 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,0))
2286 return nullopt;
2287 }
2288 51 c = MAPCOMBO(x,y);
2289
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(ispitfall(c)) return get_rpos_handle_for_world_xy(x, y, 0);
2290 return nullopt;
2291 51 }
2292 5426640 bool check_icy(newcombo const& cmb, int type)
2293 {
2294
2/2
✓ Branch 0 taken 5426475 times.
✓ Branch 1 taken 165 times.
5426640 if(cmb.type != cICY)
2295 5426475 return false;
2296
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 165 times.
165 switch(type)
2297 {
2298 case ICY_BLOCK:
2299 return cmb.usrflags&cflag1;
2300 case ICY_PLAYER:
2301 165 return cmb.usrflags&cflag2;
2302 }
2303 return false;
2304 5426640 }
2305 1811404 int get_icy(int x, int y, int type)
2306 {
2307 1811404 int32_t c = MAPCOMBOL(2,x,y);
2308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1811404 times.
1811404 if(check_icy(combobuf[c], type)) return c;
2309
2310 1811404 int screen = get_screen_for_world_xy(x, y);
2311
2312 1811404 mapscr* scr = get_scr_layer_valid(screen, 2);
2313
2/2
✓ Branch 0 taken 430769 times.
✓ Branch 1 taken 1380635 times.
1811404 if (scr)
2314 {
2315
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 1380119 times.
1380635 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2316 {
2317
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 516 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
516 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2318 516 }
2319 else
2320 {
2321
3/4
✓ Branch 0 taken 3048 times.
✓ Branch 1 taken 1377071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3048 times.
1380119 if (combobuf[MAPCOMBO2(1,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2322 }
2323 1377587 }
2324 1808356 c = MAPCOMBOL(1,x,y);
2325
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1808356 times.
1808356 if(check_icy(combobuf[c], type)) return c;
2326
2327 1808356 scr = get_scr_layer_valid(screen, 1);
2328
2/2
✓ Branch 0 taken 73612 times.
✓ Branch 1 taken 1734744 times.
1808356 if (scr)
2329 {
2330
2/2
✓ Branch 0 taken 1934 times.
✓ Branch 1 taken 1732810 times.
1734744 if (get_qr(qr_OLD_BRIDGE_COMBOS))
2331 {
2332
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1934 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1934 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && !_walkflag_layer(x,y,1, scr)) return 0;
2333 1934 }
2334 else
2335 {
2336
3/4
✓ Branch 0 taken 1641 times.
✓ Branch 1 taken 1731169 times.
✓ Branch 2 taken 1641 times.
✗ Branch 3 not taken.
1732810 if (combobuf[MAPCOMBO2(0,x,y)].type == cBRIDGE && _effectflag_layer(x,y,1, scr)) return 0;
2337 }
2338 1733103 }
2339 1806715 c = MAPCOMBO(x,y);
2340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1806715 times.
1806715 if(check_icy(combobuf[c], type)) return c;
2341 1806715 return 0;
2342 1811404 }
2343
2344 13049036 static bool checkSV(int32_t x, int32_t y, int32_t flag)
2345 {
2346
8/8
✓ Branch 0 taken 13042238 times.
✓ Branch 1 taken 6798 times.
✓ Branch 2 taken 13033372 times.
✓ Branch 3 taken 8866 times.
✓ Branch 4 taken 13021740 times.
✓ Branch 5 taken 11632 times.
✓ Branch 6 taken 428468 times.
✓ Branch 7 taken 12593272 times.
13049036 if(x<0 || x>=world_w || y<0 || y>=world_h)
2347 455764 return false;
2348
2349 12593272 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
2350
2/4
✓ Branch 0 taken 12593272 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12593272 times.
12593272 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2351 return true;
2352
2353 12593272 change_rpos_handle_layer(rpos_handle, 1);
2354
2/2
✓ Branch 0 taken 7565562 times.
✓ Branch 1 taken 5027710 times.
12593272 if (rpos_handle.scr->is_valid())
2355
3/4
✓ Branch 0 taken 5027710 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3279 times.
✓ Branch 3 taken 5024431 times.
5027710 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2356 3279 return true;
2357
2358 12589993 change_rpos_handle_layer(rpos_handle, 2);
2359
2/2
✓ Branch 0 taken 10876856 times.
✓ Branch 1 taken 1713137 times.
12589993 if (rpos_handle.scr->is_valid())
2360
2/4
✓ Branch 0 taken 1713137 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1713137 times.
1713137 if (rpos_handle.sflag() == flag || rpos_handle.cflag() == flag)
2361 return true;
2362
2363 12589993 return false;
2364 13049036 }
2365
2366 6588680 bool isSVLadder(int32_t x, int32_t y)
2367 {
2368 6588680 return checkSV(x, y, mfSIDEVIEWLADDER);
2369 }
2370
2371 6460356 bool isSVPlatform(int32_t x, int32_t y)
2372 {
2373 6460356 return checkSV(x, y, mfSIDEVIEWPLATFORM);
2374 }
2375
2376 6460356 bool checkSVLadderPlatform(int32_t x, int32_t y)
2377 {
2378
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 6460356 times.
✓ Branch 2 taken 6458559 times.
✓ Branch 3 taken 1797 times.
6460356 return isSVPlatform(x,y) || (isSVLadder(x,y) && !isSVLadder(x,y-16));
2379 }
2380
2381 1637 bool isstepable(int32_t combo) //can use ladder on it
2382 {
2383
2/2
✓ Branch 0 taken 1631 times.
✓ Branch 1 taken 6 times.
1637 if(combo_class_buf[combobuf[combo].type].ladder_pass) return true;
2384
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if(combo_class_buf[combobuf[combo].type].pit)
2385 {
2386 if(combobuf[combo].usrflags&cflag4)
2387 {
2388 int32_t ldrid = current_item_id(itype_ladder);
2389 return (ldrid > -1 && itemsbuf[ldrid].flags & item_flag1);
2390 }
2391 }
2392 6 return false;
2393 1637 }
2394
2395 32780 bool isHSGrabbable(newcombo const& cmb)
2396 {
2397
2/2
✓ Branch 0 taken 373 times.
✓ Branch 1 taken 32407 times.
32780 if(cmb.type == cHSGRAB) return true;
2398 32407 return cmb.genflags & cflag1;
2399 32780 }
2400
2401 954 bool isSwitchHookable(newcombo const& cmb)
2402 {
2403
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 822 times.
954 if(cmb.type == cSWITCHHOOK) return true;
2404 822 return cmb.genflags & cflag2;
2405 954 }
2406
2407 61401 bool check_hshot(int32_t layer, int32_t x, int32_t y, bool switchhook, rpos_t *out_rpos, ffcdata **out_ffc)
2408 {
2409 61401 rpos_t cpos = rpos_t::None;
2410
2/2
✓ Branch 0 taken 64592 times.
✓ Branch 1 taken 125993 times.
61401 if(out_rpos)
2411 {
2412 125993 int32_t id = MAPCOMBO2(layer-1,x,y);
2413
2/2
✓ Branch 0 taken 28634 times.
✓ Branch 1 taken 97359 times.
125993 if(id > 0)
2414 {
2415 97359 newcombo const& cmb = combobuf[id];
2416
4/4
✓ Branch 0 taken 32738 times.
✓ Branch 1 taken 64621 times.
✓ Branch 2 taken 32296 times.
✓ Branch 3 taken 32325 times.
97359 cpos = (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb)) ? COMBOPOS_REGION(x,y) : rpos_t::None;
2417 32767 }
2418 61401 }
2419
2420 125993 ffcdata* ffc = nullptr;
2421
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 24996 times.
✓ Branch 3 taken 3393 times.
125993 if (out_ffc && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2422 {
2423 10359 for_some_ffcs([&](const ffc_handle_t& ffc_handle) {
2424
2/2
✓ Branch 0 taken 6853 times.
✓ Branch 1 taken 113 times.
6966 if (ffcIsAt(ffc_handle, x, y))
2425 {
2426 113 auto& cmb = ffc_handle.combo();
2427
4/4
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 71 times.
✓ Branch 2 taken 35 times.
✓ Branch 3 taken 36 times.
113 if (switchhook ? isSwitchHookable(cmb) : isHSGrabbable(cmb))
2428 {
2429 77 ffc = ffc_handle.ffc;
2430 77 return false;
2431 }
2432 36 }
2433 6889 return true;
2434 6896 });
2435 3393 }
2436
2437
4/4
✓ Branch 0 taken 61401 times.
✓ Branch 1 taken 64592 times.
✓ Branch 2 taken 442 times.
✓ Branch 3 taken 60959 times.
125993 if (out_rpos && cpos != rpos_t::None) *out_rpos = cpos;
2438
4/4
✓ Branch 0 taken 28389 times.
✓ Branch 1 taken 97604 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 28382 times.
125993 if (out_ffc && ffc) *out_ffc = ffc;
2439
2/2
✓ Branch 0 taken 65034 times.
✓ Branch 1 taken 60959 times.
125993 return (cpos != rpos_t::None || ffc);
2440 }
2441
2442 5195 bool ishookshottable(int32_t bx, int32_t by)
2443 {
2444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5195 times.
5195 if(!_walkflag(bx,by,1))
2445 return true;
2446
2447
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 5187 times.
5195 if (collide_object(bx, by, 1, 1))
2448 8 return false;
2449
2450 5187 bool ret = true;
2451
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 1900 times.
17461 for(int32_t i=2; i>=0; i--)
2452 {
2453 15561 int32_t c = MAPCOMBO2(i-1,bx,by);
2454 15561 int32_t t = combobuf[c].type;
2455
2456
6/6
✓ Branch 0 taken 5187 times.
✓ Branch 1 taken 10374 times.
✓ Branch 2 taken 3853 times.
✓ Branch 3 taken 1334 times.
✓ Branch 4 taken 1900 times.
✓ Branch 5 taken 1953 times.
15561 if(i == 0 && (t == cHOOKSHOTONLY || t == cLADDERHOOKSHOT)) return true;
2457
2458
3/4
✓ Branch 0 taken 11321 times.
✓ Branch 1 taken 953 times.
✓ Branch 2 taken 953 times.
✗ Branch 3 not taken.
13227 bool dried = (iswater_type(t) && DRIEDLAKE);
2459
2460 12274 int32_t b=1;
2461
2462
2/2
✓ Branch 0 taken 6109 times.
✓ Branch 1 taken 6165 times.
12274 if(bx&8) b<<=2;
2463
2464
2/2
✓ Branch 0 taken 3841 times.
✓ Branch 1 taken 8433 times.
12274 if(by&8) b<<=1;
2465
2466
7/8
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 10180 times.
✓ Branch 2 taken 2094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1115 times.
✓ Branch 5 taken 979 times.
✓ Branch 6 taken 75 times.
✓ Branch 7 taken 904 times.
12274 if(combobuf[c].walk&b && !dried && !(combo_class_buf[t].ladder_pass && t!=cLADDERONLY) && t!=cHOOKSHOTONLY)
2467 904 ret = false;
2468 12274 }
2469
2470 1900 return ret;
2471 5195 }
2472
2473 10110 bool reveal_hidden_stairs(mapscr *s, int32_t screen, bool redraw)
2474 {
2475
4/4
✓ Branch 0 taken 9531 times.
✓ Branch 1 taken 579 times.
✓ Branch 2 taken 9531 times.
✓ Branch 3 taken 579 times.
10110 if((s->stairx || s->stairy) && s->secretcombo[sSTAIRS])
2476 {
2477 579 int pos = COMBOPOS(s->stairx,s->stairy);
2478 579 s->data[pos] = s->secretcombo[sSTAIRS];
2479 579 s->cset[pos] = s->secretcset[sSTAIRS];
2480 579 s->sflag[pos] = s->secretflag[sSTAIRS];
2481
2482
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 323 times.
579 if (redraw)
2483 {
2484 768 auto [x, y] = translate_screen_coordinates_to_world(screen, s->stairx, s->stairy);
2485 768 putcombo(scrollbuf,x,y,s->data[pos],s->cset[pos]);
2486 256 }
2487
2488 579 return true;
2489 }
2490
2491 9531 return false;
2492 10110 }
2493
2494 51768 screen_handles_t create_screen_handles_one(mapscr* base_scr)
2495 {
2496 DCHECK(base_scr->is_valid());
2497
2498 51768 screen_handles_t screen_handles{};
2499 51768 screen_handles[0] = {base_scr, base_scr, base_scr->screen, 0};
2500 51768 return screen_handles;
2501 }
2502
2503 56531351 screen_handles_t create_screen_handles(mapscr* base_scr)
2504 {
2505 DCHECK(get_scr(base_scr->screen) == base_scr);
2506 DCHECK(base_scr->is_valid());
2507
2508 56531351 int screen = base_scr->screen;
2509 screen_handles_t screen_handles;
2510 56531351 screen_handles[0] = {base_scr, base_scr, screen, 0};
2511
2/2
✓ Branch 0 taken 339188106 times.
✓ Branch 1 taken 56531351 times.
395719457 for (int i = 1; i <= 6; i++)
2512 339188106 screen_handles[i] = {base_scr, get_scr_layer_valid(screen, i), screen, i};
2513 56531351 return screen_handles;
2514 }
2515
2516 106202 bool remove_screenstatecombos2(const screen_handles_t& screen_handles, bool do_layers, int32_t what1, int32_t what2)
2517 {
2518 106202 mapscr* scr = screen_handles[0].scr;
2519 106202 bool didit=false;
2520
2521
2/2
✓ Branch 0 taken 106202 times.
✓ Branch 1 taken 18691552 times.
18797754 for(int32_t i=0; i<176; i++)
2522 {
2523 18691552 newcombo const& cmb = combobuf[scr->data[i]];
2524
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 18691226 times.
18691552 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2525
4/4
✓ Branch 0 taken 18689693 times.
✓ Branch 1 taken 1533 times.
✓ Branch 2 taken 1102 times.
✓ Branch 3 taken 18688591 times.
18691226 if((cmb.type == what1) || (cmb.type== what2))
2526 {
2527 2635 scr->data[i]++;
2528 2635 didit=true;
2529 2635 }
2530 18691226 }
2531
2532
2/2
✓ Branch 0 taken 92 times.
✓ Branch 1 taken 106110 times.
106202 if (do_layers)
2533 {
2534
2/2
✓ Branch 0 taken 636660 times.
✓ Branch 1 taken 106110 times.
742770 for(int32_t j=1; j<=6; j++)
2535 {
2536 636660 mapscr* layer_scr = screen_handles[j].scr;
2537
2/2
✓ Branch 0 taken 173044 times.
✓ Branch 1 taken 463616 times.
636660 if (!layer_scr) continue;
2538
2539
2/2
✓ Branch 0 taken 30455744 times.
✓ Branch 1 taken 173044 times.
30628788 for(int32_t i=0; i<176; i++)
2540 {
2541 30455744 newcombo const& cmb = combobuf[layer_scr->data[i]];
2542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30455744 times.
30455744 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2543
4/4
✓ Branch 0 taken 30455661 times.
✓ Branch 1 taken 83 times.
✓ Branch 2 taken 265 times.
✓ Branch 3 taken 30455396 times.
30455744 if((cmb.type== what1) || (cmb.type== what2))
2544 {
2545 348 layer_scr->data[i]++;
2546 348 didit=true;
2547 348 }
2548 30455744 }
2549 173044 }
2550 106110 }
2551
2552 // 'do_layers' also means that this is called on an active temp screen, so update its ffcs.
2553
3/4
✓ Branch 0 taken 20406 times.
✓ Branch 1 taken 85796 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 20406 times.
106202 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && do_layers)
2554 {
2555 20406 word c = scr->numFFC();
2556
2/2
✓ Branch 0 taken 73350 times.
✓ Branch 1 taken 20406 times.
93756 for(word i=0; i<c; i++)
2557 {
2558 73350 ffcdata* ffc = &scr->ffcs[i];
2559 73350 newcombo const& cmb = combobuf[ffc->data];
2560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73350 times.
73350 if(cmb.usrflags&cflag16) continue; //custom state instead of normal state
2561
2/4
✓ Branch 0 taken 73350 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 73350 times.
73350 if((cmb.type== what1) || (cmb.type== what2))
2562 {
2563 zc_ffc_modify(*ffc, 1);
2564 didit=true;
2565 }
2566 73350 }
2567 20406 }
2568
2569 106202 return didit;
2570 }
2571
2572 14 bool remove_xstatecombos(const screen_handles_t& screen_handles, byte xflag, bool triggers)
2573 {
2574 14 int screen = screen_handles[0].scr->screen;
2575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2576 14 return remove_xstatecombos_mi(screen_handles, mi, xflag, triggers);
2577 }
2578 471496206 bool remove_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, byte xflag, bool triggers)
2579 {
2580 471496206 bool didit=false;
2581
2/2
✓ Branch 0 taken 471467348 times.
✓ Branch 1 taken 28858 times.
471496206 if(!getxmapflag_mi(mi, 1<<xflag)) return false;
2582
2583 28858 mapscr* s = screen_handles[0].scr;
2584 28858 int screen = s->screen;
2585 28858 bool is_active_screen = is_in_current_region(s);
2586
2587 24248394 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2588
4/4
✓ Branch 0 taken 24207920 times.
✓ Branch 1 taken 11616 times.
✓ Branch 2 taken 24206112 times.
✓ Branch 3 taken 1808 times.
24219536 if(triggers && force_ex_trigger_any(rpos_handle, xflag))
2589 1808 didit = true;
2590
2/2
✓ Branch 0 taken 63627 times.
✓ Branch 1 taken 24154101 times.
24217728 else switch (rpos_handle.ctype())
2591 {
2592 case cLOCKBLOCK: case cLOCKBLOCK2:
2593 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2594 case cCHEST: case cCHEST2:
2595 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2596 case cBOSSCHEST: case cBOSSCHEST2:
2597 {
2598 63627 auto& cmb = rpos_handle.combo();
2599
2/2
✓ Branch 0 taken 62059 times.
✓ Branch 1 taken 1568 times.
63627 if(!(cmb.usrflags&cflag16)) return; //custom state instead of normal state
2600
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 62030 times.
62059 if(cmb.attribytes[5] == xflag)
2601 {
2602 29 rpos_handle.increment_data();
2603 29 didit=true;
2604 29 }
2605 62059 break;
2606 }
2607 }
2608 24219536 });
2609
2610
4/4
✓ Branch 0 taken 28817 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 19197 times.
✓ Branch 3 taken 9620 times.
28858 if (is_active_screen && !get_qr(qr_OLD_FFC_FUNCTIONALITY))
2611 {
2612 19197 word c = s->numFFC();
2613 19197 int screen_index_offset = get_region_screen_offset(screen);
2614
2/2
✓ Branch 0 taken 36840 times.
✓ Branch 1 taken 19197 times.
56037 for (uint8_t i = 0; i < c; i++)
2615 {
2616 36840 auto ffc_handle = *s->getFFCHandle(i, screen_index_offset);
2617 36840 auto& cmb = ffc_handle.combo();
2618
3/4
✓ Branch 0 taken 36840 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 36824 times.
✓ Branch 3 taken 16 times.
36840 if(triggers && force_ex_trigger_ffc_any(ffc_handle, xflag))
2619 16 didit = true;
2620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36824 times.
36824 else switch(cmb.type)
2621 {
2622 case cLOCKBLOCK: case cLOCKBLOCK2:
2623 case cBOSSLOCKBLOCK: case cBOSSLOCKBLOCK2:
2624 case cCHEST: case cCHEST2:
2625 case cLOCKEDCHEST: case cLOCKEDCHEST2:
2626 case cBOSSCHEST: case cBOSSCHEST2:
2627 {
2628 if(!(cmb.usrflags&cflag16)) continue; //custom state instead of normal state
2629 if(cmb.attribytes[5] == xflag)
2630 {
2631 zc_ffc_modify(*ffc_handle.ffc, 1);
2632 didit=true;
2633 }
2634 break;
2635 }
2636 }
2637 36840 }
2638 19197 }
2639
2640 28858 return didit;
2641 471496206 }
2642
2643 14682265 void clear_xstatecombos(const screen_handles_t& screen_handles, bool triggers)
2644 {
2645 14682265 int screen = screen_handles[0].screen;
2646
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2647 14682265 clear_xstatecombos_mi(screen_handles, mi, triggers);
2648 14682265 }
2649
2650 14734256 void clear_xstatecombos_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2651 {
2652
2/2
✓ Branch 0 taken 471496192 times.
✓ Branch 1 taken 14734256 times.
486230448 for (int q = 0; q < 32; ++q)
2653 {
2654 471496192 remove_xstatecombos_mi(screen_handles, mi, q, triggers);
2655 471496192 }
2656 14734256 }
2657
2658 bool remove_xdoors(const screen_handles_t& screen_handles, uint dir, uint ind, bool triggers)
2659 {
2660 int screen = screen_handles[0].screen;
2661 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2662 return remove_xdoors_mi(screen_handles, mi, dir, ind, triggers);
2663 }
2664 471496192 bool remove_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, uint dir, uint ind, bool triggers)
2665 {
2666 471496192 bool didit=false;
2667
2/2
✓ Branch 0 taken 471494879 times.
✓ Branch 1 taken 1313 times.
471496192 if (!getxdoor_mi(mi, dir, ind)) return false;
2668
2669 1313 mapscr* scr = screen_handles[0].scr;
2670 1313 int screen = scr->screen;
2671 1313 bool is_active_screen = is_in_current_region(scr);
2672
2673 925665 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
2674
3/4
✓ Branch 0 taken 924352 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 924341 times.
924352 if (triggers && force_ex_door_trigger_any(rpos_handle, dir, ind))
2675 11 didit = true;
2676 else; //future door combo types?
2677 924352 });
2678
2679
2/4
✓ Branch 0 taken 1313 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1313 times.
✗ Branch 3 not taken.
1313 if (!get_qr(qr_OLD_FFC_FUNCTIONALITY) && is_active_screen)
2680 {
2681 1313 word c = scr->numFFC();
2682 1313 int screen_index_offset = get_region_screen_offset(screen);
2683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1313 times.
1313 for (uint8_t i = 0; i < c; i++)
2684 {
2685 auto ffc_handle = *scr->getFFCHandle(i, screen_index_offset);
2686 if (triggers && force_ex_door_trigger_ffc_any(ffc_handle, dir, ind))
2687 didit = true;
2688 else; //future door combo types?
2689 }
2690 1313 }
2691
2692 1313 return didit;
2693 471496192 }
2694
2695 14682265 void clear_xdoors(const screen_handles_t& screen_handles, bool triggers)
2696 {
2697 14682265 int screen = screen_handles[0].screen;
2698
2/2
✓ Branch 0 taken 387833 times.
✓ Branch 1 taken 14294432 times.
14682265 int mi = mapind(cur_map, screen >= 0x80 ? home_screen : screen);
2699 14682265 return clear_xdoors_mi(screen_handles, mi, triggers);
2700 }
2701
2702 14734256 void clear_xdoors_mi(const screen_handles_t& screen_handles, int32_t mi, bool triggers)
2703 {
2704
2/2
✓ Branch 0 taken 58937024 times.
✓ Branch 1 taken 14734256 times.
73671280 for (int dir = 0; dir < 4; ++dir)
2705
2/2
✓ Branch 0 taken 471496192 times.
✓ Branch 1 taken 58937024 times.
530433216 for (int q = 0; q < 8; ++q)
2706 530433216 remove_xdoors_mi(screen_handles, mi, dir, q, triggers);
2707 14734256 }
2708
2709 763 bool remove_lockblocks(const screen_handles_t& screen_handles)
2710 {
2711 763 return remove_screenstatecombos2(screen_handles, true, cLOCKBLOCK, cLOCKBLOCK2);
2712 }
2713
2714 98 bool remove_bosslockblocks(const screen_handles_t& screen_handles)
2715 {
2716 98 return remove_screenstatecombos2(screen_handles, true, cBOSSLOCKBLOCK, cBOSSLOCKBLOCK2);
2717 }
2718
2719 76553 bool remove_chests(const screen_handles_t& screen_handles)
2720 {
2721 76553 return remove_screenstatecombos2(screen_handles, true, cCHEST, cCHEST2);
2722 }
2723
2724 2484 bool remove_lockedchests(const screen_handles_t& screen_handles)
2725 {
2726 2484 return remove_screenstatecombos2(screen_handles, true, cLOCKEDCHEST, cLOCKEDCHEST2);
2727 }
2728
2729 26212 bool remove_bosschests(const screen_handles_t& screen_handles)
2730 {
2731 26212 return remove_screenstatecombos2(screen_handles, true, cBOSSCHEST, cBOSSCHEST2);
2732 }
2733
2734 1384361 void delete_fireball_shooter(const rpos_handle_t& rpos_handle)
2735 {
2736 1384361 int32_t ct=rpos_handle.ctype();
2737
2738
6/6
✓ Branch 0 taken 1383741 times.
✓ Branch 1 taken 620 times.
✓ Branch 2 taken 1383489 times.
✓ Branch 3 taken 252 times.
✓ Branch 4 taken 1383381 times.
✓ Branch 5 taken 108 times.
1384361 if(ct!=cL_STATUE && ct!=cR_STATUE && ct!=cC_STATUE)
2739 1383381 return;
2740
2741 2465 auto [cx, cy] = rpos_handle.xy();
2742
3/4
✓ Branch 0 taken 252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 620 times.
✓ Branch 3 taken 108 times.
980 switch(ct)
2743 {
2744 case cL_STATUE:
2745 620 cx += 4;
2746 620 cy += 7;
2747 620 break;
2748
2749 case cR_STATUE:
2750 252 cx -= 8;
2751 252 cy -= 1;
2752 252 break;
2753
2754 case cC_STATUE:
2755 108 break;
2756 }
2757
2758
2/2
✓ Branch 0 taken 980 times.
✓ Branch 1 taken 1485 times.
2465 for(int32_t j=0; j<guys.Count(); j++)
2759 {
2760 // Finds the smallest enemy ID
2761
9/10
✓ Branch 0 taken 399 times.
✓ Branch 1 taken 1086 times.
✓ Branch 2 taken 399 times.
✓ Branch 3 taken 1086 times.
✓ Branch 4 taken 346 times.
✓ Branch 5 taken 53 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 53 times.
✓ Branch 8 taken 346 times.
✗ Branch 9 not taken.
2970 if((int32_t(guys.spr(j)->x)==cx)&&(int32_t(guys.spr(j)->y)==cy)&&(guysbuf[(guys.spr(j)->id)&0xFFF].flags & guy_fire))
2762 {
2763 346 guys.del(j);
2764 346 }
2765 1485 }
2766 1384361 }
2767
2768 15 static int32_t findtrigger(int32_t screen)
2769 {
2770 15 int32_t checkflag=0;
2771 15 int32_t ret = 0;
2772
2773 mapscr* screens[7];
2774
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 15 times.
120 for (int32_t j = 0; j <= 6; j++)
2775 {
2776 105 screens[j] = get_scr_layer_valid(screen, j);
2777 105 }
2778
2779 15 bool sflag = false;
2780
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 15 times.
2655 for(word j=0; j<176; j++)
2781 {
2782
2/2
✓ Branch 0 taken 26752 times.
✓ Branch 1 taken 2640 times.
29392 for(int32_t layer = -1; layer < 6; ++layer)
2783 {
2784 26752 mapscr* scr = screens[layer+1];
2785
2/2
✓ Branch 0 taken 16544 times.
✓ Branch 1 taken 10208 times.
26752 if (!scr) continue;
2786
2787
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if(sflag)
2788 8272 checkflag = scr->sflag[j];
2789 else
2790 8272 checkflag = combobuf[scr->data[j]].flag;
2791 16544 sflag = !sflag;
2792
2/2
✓ Branch 0 taken 8272 times.
✓ Branch 1 taken 8272 times.
16544 if (sflag) --layer;
2793
2794
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 16534 times.
16544 switch(checkflag)
2795 {
2796 case mfANYFIRE:
2797 case mfSTRONGFIRE:
2798 case mfMAGICFIRE:
2799 case mfDIVINEFIRE:
2800 case mfARROW:
2801 case mfSARROW:
2802 case mfGARROW:
2803 case mfSBOMB:
2804 case mfBOMB:
2805 case mfBRANG:
2806 case mfMBRANG:
2807 case mfFBRANG:
2808 case mfWANDMAGIC:
2809 case mfREFMAGIC:
2810 case mfREFFIREBALL:
2811 case mfSWORD:
2812 case mfWSWORD:
2813 case mfMSWORD:
2814 case mfXSWORD:
2815 case mfSWORDBEAM:
2816 case mfWSWORDBEAM:
2817 case mfMSWORDBEAM:
2818 case mfXSWORDBEAM:
2819 case mfHOOKSHOT:
2820 case mfWAND:
2821 case mfHAMMER:
2822 case mfSTRIKE:
2823 10 ret += 1;
2824 10 break;
2825 }
2826 16544 }
2827 2640 }
2828
2829 15 return ret;
2830 }
2831
2832 11738 static void log_trigger_secret_reason(TriggerSource source)
2833 {
2834
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11299 times.
11738 if (source == TriggerSource::Singular)
2835 {
2836 439 Z_eventlog("Restricted Screen Secrets triggered\n");
2837 439 }
2838 else
2839 {
2840 11299 const char* source_str = "";
2841
7/12
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 7178 times.
✓ Branch 3 taken 856 times.
✓ Branch 4 taken 2733 times.
✓ Branch 5 taken 475 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 52 times.
✓ Branch 8 taken 4 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
11299 switch (source)
2842 {
2843 case TriggerSource::Singular: break;
2844 7178 case TriggerSource::Unspecified: source_str = "unspecified means"; break;
2845 856 case TriggerSource::EnemiesScreenFlag: source_str = "the 'Enemies->Secret' screen flag"; break;
2846 2733 case TriggerSource::SecretsScreenState: source_str = "the 'Secrets' screen state"; break;
2847 475 case TriggerSource::Script: source_str = "a script"; break;
2848 1 case TriggerSource::ItemsSecret: source_str = "Items->Secrets"; break;
2849 52 case TriggerSource::GenericCombo: source_str = "Generic Combo"; break;
2850 4 case TriggerSource::LightTrigger: source_str = "Light Triggers"; break;
2851 case TriggerSource::SCC: source_str = "SCC"; break;
2852 case TriggerSource::CheatTemp: source_str = "Cheat (Temp)"; break;
2853 case TriggerSource::CheatPerm: source_str = "Cheat (Perm)"; break;
2854 }
2855 11299 Z_eventlog("Screen Secrets triggered by %s\n", source_str);
2856 }
2857 11738 }
2858
2859 // single:
2860 // >-1 : the singular triggering combo
2861 // -1: triggered by some other cause
2862 11530 void trigger_secrets_for_screen(TriggerSource source, mapscr* scr, bool high16only, int32_t single)
2863 {
2864 11530 log_trigger_secret_reason(source);
2865
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single < 0)
2866 11091 get_screen_state(scr->screen).triggered_secrets = true;
2867
2868 11530 bool do_replay_comment = true;
2869 11530 bool from_active_screen = true;
2870 11530 trigger_secrets_for_screen_internal(create_screen_handles(scr), from_active_screen, high16only, single, do_replay_comment);
2871
2872 // Respect secret state carryovers for active screens.
2873
2/2
✓ Branch 0 taken 439 times.
✓ Branch 1 taken 11091 times.
11530 if (single >= 0) return;
2874
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 11068 times.
11091 if(scr->nocarry&mSECRET) return;
2875 11068 int cmap = scr->map;
2876 11068 int cscr = scr->screen;
2877 11068 int nmap=TheMaps[((cmap)*MAPSCRS)+cscr].nextmap;
2878 11068 int nscr=TheMaps[((cmap)*MAPSCRS)+cscr].nextscr;
2879
2880 11068 std::vector<int32_t> done;
2881
2/2
✓ Branch 0 taken 10896 times.
✓ Branch 1 taken 172 times.
11068 bool looped = (nmap==cmap+1 && nscr==cscr);
2882
2883
6/6
✓ Branch 0 taken 484 times.
✓ Branch 1 taken 11001 times.
✓ Branch 2 taken 67 times.
✓ Branch 3 taken 417 times.
✓ Branch 4 taken 417 times.
✓ Branch 5 taken 11068 times.
11485 while((nmap!=0) && !looped && !(nscr>=128))
2884 {
2885
7/8
✓ Branch 0 taken 317 times.
✓ Branch 1 taken 100 times.
✓ Branch 2 taken 74 times.
✓ Branch 3 taken 243 times.
✓ Branch 4 taken 74 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4 times.
✓ Branch 7 taken 70 times.
417 if (nmap - 1 == cur_map && is_in_current_region(nscr) && !get_screen_state(nscr).triggered_secrets)
2886 {
2887
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
2888
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
4 trigger_secrets_for_screen_internal(create_screen_handles(get_scr(nscr)), from_active_screen, high16only, single, do_replay_comment);
2889
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 get_screen_state(nscr).triggered_secrets = true;
2890 4 }
2891
2892 417 cmap=nmap;
2893 417 cscr=nscr;
2894 417 nmap=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextmap;
2895 417 nscr=TheMaps[((cmap-1)*MAPSCRS)+cscr].nextscr;
2896
2897
2/2
✓ Branch 0 taken 386 times.
✓ Branch 1 taken 417 times.
803 for(auto it = done.begin(); it != done.end(); it++)
2898 {
2899
2/2
✓ Branch 0 taken 319 times.
✓ Branch 1 taken 67 times.
386 if(*it == ((nmap-1)<<7)+nscr)
2900 67 looped = true;
2901 386 }
2902
2903
1/2
✓ Branch 0 taken 417 times.
✗ Branch 1 not taken.
417 done.push_back(((nmap-1)<<7)+nscr);
2904 }
2905 11530 }
2906
2907 2437 void trigger_secrets_for_screen(TriggerSource source, int32_t screen, bool high16only, int32_t single)
2908 {
2909 2437 trigger_secrets_for_screen(source, get_scr(screen), high16only, single);
2910 2437 }
2911
2912 18007 void trigger_secrets_for_screen_internal(const screen_handles_t& screen_handles, bool from_active_screen, bool high16only, int32_t single, bool do_replay_comment)
2913 {
2914 18007 mapscr* scr = screen_handles[0].scr;
2915 18007 int screen = scr->screen;
2916
2917 // TODO(replays): No real reason for "do_replay_comment" to exist - I just did not want to update many replays when fixing
2918 // slopes in sideview mode (which required loading nearby screens in loadscr).
2919 // TODO(replays): This should just use `screen`.
2920
3/4
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 539 times.
✓ Branch 3 taken 17468 times.
18007 if (replay_is_active() && do_replay_comment)
2921
4/6
✓ Branch 0 taken 11534 times.
✓ Branch 1 taken 5934 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11534 times.
✓ Branch 4 taken 17468 times.
✗ Branch 5 not taken.
17468 replay_step_comment(fmt::format("trigger secrets scr={}", from_active_screen && scr != special_warp_return_scr ? screen : cur_screen));
2922
2923
2/2
✓ Branch 0 taken 6473 times.
✓ Branch 1 taken 11534 times.
18007 if (from_active_screen)
2924 {
2925 5442998 for_every_combo_in_screen(screen_handles, [&](const auto& handle) {
2926
2/4
✓ Branch 0 taken 5429776 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1688 times.
✗ Branch 3 not taken.
5661701 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
2927 230237 return trig.trigger_flags.get(TRIGFLAG_SECRETSTR);
2928 }, ctrigSECRETS);
2929 5431464 });
2930 11534 }
2931
2932 18007 int32_t ft=0; //Flag trigger?
2933 18007 int32_t msflag=0; // Misc. secret flag
2934
2935
2/2
✓ Branch 0 taken 3169232 times.
✓ Branch 1 taken 18007 times.
3187239 for(int32_t i=0; i<176; i++) //Do the 'trigger flags' (non 16-31)
2936 {
2937
4/4
✓ Branch 0 taken 77264 times.
✓ Branch 1 taken 3091968 times.
✓ Branch 2 taken 439 times.
✓ Branch 3 taken 76825 times.
3169232 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2938
2939 // Remember the misc. secret flag; if triggered, use this instead
2940
4/4
✓ Branch 0 taken 114511 times.
✓ Branch 1 taken 2977896 times.
✓ Branch 2 taken 49462 times.
✓ Branch 3 taken 65049 times.
3092407 if(scr->sflag[i]>=mfSECRETS01 && scr->sflag[i]<=mfSECRETS16)
2941 65049 msflag=sSECRET01+(scr->sflag[i]-mfSECRETS01);
2942
4/4
✓ Branch 0 taken 47230 times.
✓ Branch 1 taken 2980128 times.
✓ Branch 2 taken 46999 times.
✓ Branch 3 taken 231 times.
3027358 else if(combobuf[scr->data[i]].flag>=mfSECRETS01 && combobuf[scr->data[i]].flag<=mfSECRETS16)
2943 231 msflag=sSECRET01+(combobuf[scr->data[i]].flag-mfSECRETS01);
2944 else
2945 3027127 msflag=0;
2946
2947
4/4
✓ Branch 0 taken 921256 times.
✓ Branch 1 taken 2171151 times.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 921184 times.
3092407 if(!high16only || single>=0)
2948 {
2949 2171223 int32_t newflag = -1;
2950
2951
2/2
✓ Branch 0 taken 4342446 times.
✓ Branch 1 taken 2171223 times.
6513669 for(int32_t iter=0; iter<2; ++iter)
2952 {
2953 4342446 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
2954
2955
2/2
✓ Branch 0 taken 2171223 times.
✓ Branch 1 taken 2171223 times.
4342446 if(iter==1) checkflag=scr->sflag[i]; //Placed
2956
2957 4342446 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
2958
2/2
✓ Branch 0 taken 4330212 times.
✓ Branch 1 taken 12234 times.
4342446 if (ft != -1) //Change the combos for the secret
2959 {
2960 // Use misc. secret flag instead if one is present
2961
2/2
✓ Branch 0 taken 12202 times.
✓ Branch 1 taken 32 times.
12234 if(msflag!=0)
2962 32 ft=msflag;
2963
2964 12234 rpos_handle_t rpos_handle;
2965
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2966 {
2967 5867 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
2968 5867 screen_combo_modify_preroutine(rpos_handle);
2969 5867 }
2970
2971
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12234 times.
12234 if(ft==sSECNEXT)
2972 {
2973 scr->data[i]++;
2974 }
2975 else
2976 {
2977 12234 scr->data[i] = scr->secretcombo[ft];
2978 12234 scr->cset[i] = scr->secretcset[ft];
2979 }
2980 12234 newflag = scr->secretflag[ft];
2981
2982
2/2
✓ Branch 0 taken 6367 times.
✓ Branch 1 taken 5867 times.
12234 if (from_active_screen)
2983 5867 screen_combo_modify_postroutine(rpos_handle);
2984 12234 }
2985 4342446 }
2986
2987
2/2
✓ Branch 0 taken 2158995 times.
✓ Branch 1 taken 12228 times.
2171223 if(newflag >-1) scr->sflag[i] = newflag; //Tiered secret
2988
2989
2/2
✓ Branch 0 taken 13027338 times.
✓ Branch 1 taken 2171223 times.
15198561 for(int32_t j=1; j<=6; j++) //Layers
2990 {
2991 13027338 mapscr* layer_scr = screen_handles[j].scr;
2992
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 9841541 times.
13027338 if (!layer_scr) continue;
2993
2994
3/4
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 3185072 times.
✓ Branch 2 taken 725 times.
✗ Branch 3 not taken.
3185797 if(single>=0 && i!=single) continue; //If it's got a singular flag and i isn't where the flag is
2995
2996 3185797 int32_t newflag2 = -1;
2997
2998 // Remember the misc. secret flag; if triggered, use this instead
2999
4/4
✓ Branch 0 taken 14182 times.
✓ Branch 1 taken 3171615 times.
✓ Branch 2 taken 4773 times.
✓ Branch 3 taken 9409 times.
3185797 if(layer_scr->sflag[i]>=mfSECRETS01 && layer_scr->sflag[i]<=mfSECRETS16)
3000 9409 msflag=sSECRET01+(layer_scr->sflag[i]-mfSECRETS01);
3001
4/4
✓ Branch 0 taken 126931 times.
✓ Branch 1 taken 3049457 times.
✓ Branch 2 taken 126560 times.
✓ Branch 3 taken 371 times.
3176388 else if(combobuf[layer_scr->data[i]].flag>=mfSECRETS01 && combobuf[layer_scr->data[i]].flag<=mfSECRETS16)
3002 371 msflag=sSECRET01+(combobuf[layer_scr->data[i]].flag-mfSECRETS01);
3003 else
3004 3176017 msflag=0;
3005
3006
2/2
✓ Branch 0 taken 6371594 times.
✓ Branch 1 taken 3185797 times.
9557391 for(int32_t iter=0; iter<2; ++iter)
3007 {
3008 6371594 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3009
2/2
✓ Branch 0 taken 3185797 times.
✓ Branch 1 taken 3185797 times.
6371594 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3010
3011 6371594 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3012
2/2
✓ Branch 0 taken 6371116 times.
✓ Branch 1 taken 478 times.
6371594 if (ft != -1) //Change the combos for the secret
3013 {
3014 // Use misc. secret flag instead if one is present
3015
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 2 times.
478 if(msflag!=0)
3016 2 ft=msflag;
3017
3018
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 478 times.
478 if(ft==sSECNEXT)
3019 {
3020 layer_scr->data[i]++;
3021 }
3022 else
3023 {
3024 478 layer_scr->data[i] = layer_scr->secretcombo[ft];
3025 478 layer_scr->cset[i] = layer_scr->secretcset[ft];
3026 }
3027 478 newflag2 = layer_scr->secretflag[ft];
3028 478 int32_t c=layer_scr->data[i];
3029 478 int32_t cs=layer_scr->cset[i];
3030
3031
3/4
✓ Branch 0 taken 406 times.
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 406 times.
✗ Branch 3 not taken.
478 if (from_active_screen && combobuf[c].type==cSPINTILE1) //Surely this means we can have spin tiles on layers 3+? Isn't that bad? ~Joe123
3032 {
3033 auto [offx, offy] = translate_screen_coordinates_to_world(screen, COMBOX(i), COMBOY(i));
3034 addenemy(screen,offx,offy,(cs<<12)+eSPINTILE1,combobuf[c].o_tile+zc_max(1,combobuf[c].frames));
3035 }
3036 478 }
3037 6371594 }
3038
3039
2/2
✓ Branch 0 taken 478 times.
✓ Branch 1 taken 3185319 times.
3185797 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered secret
3040 3185797 }
3041 2171223 }
3042 3092407 }
3043
3044 18007 word c = scr->numFFC();
3045
2/2
✓ Branch 0 taken 506903 times.
✓ Branch 1 taken 18007 times.
524910 for(word i=0; i<c; i++) //FFC 'trigger flags'
3046 {
3047
3/4
✓ Branch 0 taken 492983 times.
✓ Branch 1 taken 13920 times.
✓ Branch 2 taken 13920 times.
✗ Branch 3 not taken.
506903 if(single>=0) if(i+176!=single) continue;
3048
3049
3/4
✓ Branch 0 taken 166605 times.
✓ Branch 1 taken 326378 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 166605 times.
492983 if((!high16only)||(single>=0))
3050 {
3051 //for (int32_t iter=0; iter<1; ++iter) // Only one kind of FFC flag now.
3052 {
3053 326378 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3054 //No placed flags yet
3055
3056 326378 ft = combo_trigger_flag_to_secret_combo_index(checkflag);
3057
2/2
✓ Branch 0 taken 326347 times.
✓ Branch 1 taken 31 times.
326378 if (ft != -1) //Change the ffc's combo
3058 {
3059
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if(ft==sSECNEXT)
3060 {
3061 zc_ffc_modify(scr->ffcs[i], 1);
3062 }
3063 else
3064 {
3065 31 zc_ffc_set(scr->ffcs[i], scr->secretcombo[ft]);
3066 31 scr->ffcs[i].cset = scr->secretcset[ft];
3067 }
3068 31 }
3069 }
3070 326378 }
3071 492983 }
3072
3073
2/2
✓ Branch 0 taken 15610 times.
✓ Branch 1 taken 2397 times.
18007 if(checktrigger) //Hit all triggers->16-31
3074 {
3075 2397 checktrigger=false;
3076
3077
2/2
✓ Branch 0 taken 2388 times.
✓ Branch 1 taken 9 times.
2397 if(scr->flags6&fTRIGGERF1631)
3078 {
3079 9 int32_t tr = findtrigger(screen); //Normal flags
3080
3081
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 4 times.
9 if(tr)
3082 {
3083 5 Z_eventlog("Hit All Triggers->16-31 not fulfilled (%d trigger flag%s remain).\n", tr, tr>1?"s":"");
3084 5 goto endhe;
3085 }
3086 4 }
3087 2392 }
3088
3089
2/2
✓ Branch 0 taken 3168352 times.
✓ Branch 1 taken 18002 times.
3186354 for(int32_t i=0; i<176; i++) // Do the 16-31 secrets
3090 {
3091 //If it's an enemies->secret screen, only do the high 16 if told to
3092 //That way you can have secret and burn/bomb entrance separately
3093 3168352 bool old_enem_secret = get_qr(qr_ENEMIES_SECRET_ONLY_16_31);
3094
6/6
✓ Branch 0 taken 2780624 times.
✓ Branch 1 taken 387728 times.
✓ Branch 2 taken 85184 times.
✓ Branch 3 taken 3083168 times.
✓ Branch 4 taken 19536 times.
✓ Branch 5 taken 65648 times.
3168352 if(((!(old_enem_secret && (scr->flags2&fCLEARSECRET)) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM))
3095 {
3096 3102704 int32_t newflag = -1;
3097
3098
2/2
✓ Branch 0 taken 6205408 times.
✓ Branch 1 taken 3102704 times.
9308112 for(int32_t iter=0; iter<2; ++iter)
3099 {
3100 6205408 int32_t checkflag=combobuf[scr->data[i]].flag; //Inherent
3101
3102
2/2
✓ Branch 0 taken 3102704 times.
✓ Branch 1 taken 3102704 times.
6205408 if(iter==1) checkflag=scr->sflag[i]; //Placed
3103
3104
4/4
✓ Branch 0 taken 161185 times.
✓ Branch 1 taken 6044223 times.
✓ Branch 2 taken 94853 times.
✓ Branch 3 taken 66332 times.
6205408 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3105 {
3106 66332 rpos_handle_t rpos_handle;
3107
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3108 {
3109 56380 rpos_handle = get_rpos_handle_for_scr(scr, 0, i);
3110 56380 screen_combo_modify_preroutine(rpos_handle);
3111 56380 }
3112
3113 66332 scr->data[i] = scr->secretcombo[checkflag-16+4];
3114 66332 scr->cset[i] = scr->secretcset[checkflag-16+4];
3115 66332 newflag = scr->secretflag[checkflag-16+4];
3116
3117
2/2
✓ Branch 0 taken 9952 times.
✓ Branch 1 taken 56380 times.
66332 if (from_active_screen)
3118 56380 screen_combo_modify_postroutine(rpos_handle);
3119 66332 }
3120 6205408 }
3121
3122
2/2
✓ Branch 0 taken 3036396 times.
✓ Branch 1 taken 66308 times.
3102704 if(newflag >-1) scr->sflag[i] = newflag; //Tiered flag
3123
3124
2/2
✓ Branch 0 taken 18616224 times.
✓ Branch 1 taken 3102704 times.
21718928 for(int32_t j=1; j<=6; j++) //Layers
3125 {
3126 18616224 mapscr* layer_scr = screen_handles[j].scr;
3127
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 13749472 times.
18616224 if (!layer_scr) continue;
3128
3129 4866752 int32_t newflag2 = -1;
3130
3131
2/2
✓ Branch 0 taken 9733504 times.
✓ Branch 1 taken 4866752 times.
14600256 for(int32_t iter=0; iter<2; ++iter)
3132 {
3133 9733504 int32_t checkflag=combobuf[layer_scr->data[i]].flag; //Inherent
3134
3135
2/2
✓ Branch 0 taken 4866752 times.
✓ Branch 1 taken 4866752 times.
9733504 if(iter==1) checkflag=layer_scr->sflag[i]; //Placed
3136
3137
4/4
✓ Branch 0 taken 151246 times.
✓ Branch 1 taken 9582258 times.
✓ Branch 2 taken 131622 times.
✓ Branch 3 taken 19624 times.
9733504 if((checkflag > 15)&&(checkflag < 32)) //If we've got a 16->32 flag change the combo
3138 {
3139 19624 layer_scr->data[i] = layer_scr->secretcombo[checkflag-16+4];
3140 19624 layer_scr->cset[i] = layer_scr->secretcset[checkflag-16+4];
3141 19624 newflag2 = layer_scr->secretflag[checkflag-16+4];
3142 19624 }
3143 9733504 }
3144
3145
2/2
✓ Branch 0 taken 4847128 times.
✓ Branch 1 taken 19624 times.
4866752 if(newflag2 >-1) layer_scr->sflag[i] = newflag2; //Tiered flag
3146 4866752 }
3147 3102704 }
3148 3168352 }
3149
3150
2/2
✓ Branch 0 taken 506743 times.
✓ Branch 1 taken 18002 times.
524745 for(word i=0; i<c; i++) // FFCs
3151 {
3152
6/6
✓ Branch 0 taken 466852 times.
✓ Branch 1 taken 39891 times.
✓ Branch 2 taken 15367 times.
✓ Branch 3 taken 491376 times.
✓ Branch 4 taken 3530 times.
✓ Branch 5 taken 11837 times.
506743 if((!(scr->flags2&fCLEARSECRET) /*Enemies->Secret*/ && single < 0) || high16only || scr->flags4&fENEMYSCRTPERM)
3153 {
3154 494906 int32_t checkflag=combobuf[scr->ffcs[i].data].flag; //Inherent
3155
3156 //No placed flags yet
3157
4/4
✓ Branch 0 taken 68 times.
✓ Branch 1 taken 494838 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 12 times.
494906 if((checkflag > 15)&&(checkflag < 32)) //If we find a flag, change the combo
3158 {
3159
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 3 times.
12 if (from_active_screen)
3160 9 zc_ffc_set(scr->ffcs[i], scr->secretcombo[checkflag - 16 + 4]);
3161 else
3162 3 scr->ffcs[i].data = scr->secretcombo[checkflag - 16 + 4];
3163 12 scr->ffcs[i].cset = scr->secretcset[checkflag-16+4];
3164 12 }
3165 494906 }
3166 524745 }
3167
3168 endhe:
3169
3170
1/2
✓ Branch 0 taken 18007 times.
✗ Branch 1 not taken.
18007 if (scr->flags4&fDISABLETIME) //Finish timed warp if 'Secrets Disable Timed Warp'
3171 {
3172 if (from_active_screen)
3173 activated_timed_warp = true;
3174 scr->timedwarptics = 0;
3175 }
3176 18007 }
3177
3178 // x,y are world coordinates.
3179 // Returns true if there is a flag (either combo, screen, or ffc) at (x, y).
3180 // Out parameters will be set if the flag is Trigger->Self, which modifies how secrets will be triggered.
3181 13508239 static bool has_flag_trigger(int32_t x, int32_t y, int32_t flag, rpos_t& out_rpos, bool& out_single16)
3182 {
3183
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13508239 times.
13508239 if (!is_in_world_bounds(x, y)) return false;
3184
3185 13508239 bool found_cflag = false;
3186 13508239 bool found_nflag = false;
3187 13508239 bool single16 = false;
3188 13508239 rpos_t rpos = rpos_t::None;
3189
3190
2/2
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 94545481 times.
108051636 for (int32_t layer = -1; layer < 6; layer++)
3191 {
3192
2/2
✓ Branch 0 taken 94543397 times.
✓ Branch 1 taken 2084 times.
94545481 if (MAPFLAG2(layer, x, y) == flag)
3193 {
3194 2084 found_nflag = true;
3195 2084 break;
3196 }
3197 94543397 }
3198
3199
2/2
✓ Branch 0 taken 13507935 times.
✓ Branch 1 taken 94556397 times.
108064332 for (int32_t layer = -1; layer < 6; layer++)
3200 {
3201
2/2
✓ Branch 0 taken 94556093 times.
✓ Branch 1 taken 304 times.
94556397 if (MAPCOMBOFLAG2(layer, x, y) == flag)
3202 {
3203 304 found_cflag = true;
3204 304 break;
3205 }
3206 94556093 }
3207
3208
2/2
✓ Branch 0 taken 94557673 times.
✓ Branch 1 taken 13508239 times.
108065912 for (int32_t i=-1; i<6; i++) // Look for Trigger->Self on all layers
3209 {
3210
2/2
✓ Branch 0 taken 94543085 times.
✓ Branch 1 taken 14588 times.
94557673 if (found_nflag) // Trigger->Self (a.k.a Singular) is inherent
3211 {
3212
3/4
✓ Branch 0 taken 112 times.
✓ Branch 1 taken 14476 times.
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
14588 if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE) && (MAPFLAG2(i, x, y) == flag))
3213 {
3214 112 rpos = COMBOPOS_REGION(x, y);
3215 112 }
3216
3/4
✓ Branch 0 taken 52 times.
✓ Branch 1 taken 14424 times.
✓ Branch 2 taken 52 times.
✗ Branch 3 not taken.
14476 else if ((MAPCOMBOFLAG2(i, x, y) == mfSINGLE16) && (MAPFLAG2(i, x, y) == flag))
3217 {
3218 52 rpos = COMBOPOS_REGION(x, y);
3219 52 single16 = true;
3220 52 }
3221 14588 }
3222
3223
2/2
✓ Branch 0 taken 94555545 times.
✓ Branch 1 taken 2128 times.
94557673 if (found_cflag) // Trigger->Self (a.k.a Singular) is non-inherent
3224 {
3225
3/4
✓ Branch 0 taken 255 times.
✓ Branch 1 taken 1873 times.
✓ Branch 2 taken 255 times.
✗ Branch 3 not taken.
2128 if ((MAPFLAG2(i, x, y) == mfSINGLE) && (MAPCOMBOFLAG2(i, x, y) == flag))
3226 {
3227 255 rpos = COMBOPOS_REGION(x, y);
3228 255 }
3229
3/4
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1853 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
1873 else if ((MAPFLAG2(i, x, y) == mfSINGLE16) && (MAPCOMBOFLAG2(i, x, y) == flag))
3230 {
3231 20 rpos = COMBOPOS_REGION(x, y);
3232 20 single16 = true;
3233 20 }
3234 2128 }
3235 94557673 }
3236
3237 13508239 out_rpos = rpos;
3238 13508239 out_single16 = single16;
3239
4/4
✓ Branch 0 taken 13506155 times.
✓ Branch 1 taken 2084 times.
✓ Branch 2 taken 13505853 times.
✓ Branch 3 taken 302 times.
13508239 return found_nflag || found_cflag || MAPFFCOMBOFLAG(x,y) == flag;
3240 13508239 }
3241
3242 4457867 bool trigger_secrets_if_flag(int32_t x, int32_t y, int32_t flag, bool setflag)
3243 {
3244
8/8
✓ Branch 0 taken 4457627 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 4455730 times.
✓ Branch 3 taken 1897 times.
✓ Branch 4 taken 4455210 times.
✓ Branch 5 taken 520 times.
✓ Branch 6 taken 952 times.
✓ Branch 7 taken 4454258 times.
4457867 if (x < -16 || y < -16 || x >= world_w || y >= world_h) return false;
3245
3246 4454258 mapscr* scr = NULL;
3247 4454258 int32_t screen = -1;
3248 4454258 rpos_t trigger_rpos = rpos_t::None;
3249 4454258 bool single16 = false;
3250
3251 4454258 std::vector<std::pair<int, int>> coords;
3252
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y});
3253
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y});
3254
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x, y + 15});
3255
1/2
✓ Branch 0 taken 4454258 times.
✗ Branch 1 not taken.
4454258 coords.push_back({x + 15, y + 15});
3256 4454258 std::vector<rpos_t> rposes_seen;
3257
2/2
✓ Branch 0 taken 4451861 times.
✓ Branch 1 taken 17811750 times.
84483617 for (auto [x, y] : coords)
3258 {
3259
2/4
✓ Branch 0 taken 17811750 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17811750 times.
✗ Branch 3 not taken.
35623500 rpos_t rpos = COMBOPOS_REGION_B(x, y);
3260
2/2
✓ Branch 0 taken 17599367 times.
✓ Branch 1 taken 212383 times.
17811750 if (rpos == rpos_t::None)
3261 212383 continue;
3262
3263
4/6
✓ Branch 0 taken 17599367 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17599367 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
✓ Branch 5 taken 17599356 times.
35198734 if (MAPFFCOMBOFLAG(x, y) == flag)
3264 {
3265
2/4
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
22 screen = get_screen_for_world_xy(x, y);
3266 11 break;
3267 }
3268
3269 17599356 bool seen = false;
3270
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 22128287 times.
35636526 for (rpos_t r : rposes_seen)
3271 {
3272
2/2
✓ Branch 0 taken 18037170 times.
✓ Branch 1 taken 4091117 times.
22128287 if (r == rpos)
3273 {
3274 4091117 seen = true;
3275 4091117 break;
3276 }
3277 }
3278
2/2
✓ Branch 0 taken 13508239 times.
✓ Branch 1 taken 4091117 times.
17599356 if (seen)
3279 4091117 continue;
3280
3281
1/2
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
13508239 rposes_seen.push_back(rpos);
3282
4/6
✓ Branch 0 taken 13508239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13508239 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2386 times.
✓ Branch 5 taken 13505853 times.
27016478 if (has_flag_trigger(x, y, flag, trigger_rpos, single16))
3283 {
3284
2/4
✓ Branch 0 taken 2386 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2386 times.
✗ Branch 3 not taken.
4772 screen = get_screen_for_world_xy(x, y);
3285 2386 break;
3286 }
3287 }
3288
3289
3/4
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
✓ Branch 2 taken 2397 times.
✗ Branch 3 not taken.
4454258 if (screen != -1) scr = get_scr(screen);
3290
2/2
✓ Branch 0 taken 2397 times.
✓ Branch 1 taken 4451861 times.
4454258 if (!scr) return false;
3291
3292
2/2
✓ Branch 0 taken 1958 times.
✓ Branch 1 taken 439 times.
2397 if (trigger_rpos == rpos_t::None)
3293 {
3294 1958 checktrigger = true;
3295
1/2
✓ Branch 0 taken 1958 times.
✗ Branch 1 not taken.
1958 trigger_secrets_for_screen(TriggerSource::Unspecified, screen);
3296 1958 }
3297 else
3298 {
3299 439 checktrigger = true;
3300
2/4
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 439 times.
✗ Branch 3 not taken.
439 trigger_secrets_for_screen(TriggerSource::Singular, scr, single16, RPOS_TO_POS(trigger_rpos));
3301 }
3302
3303
1/2
✓ Branch 0 taken 2397 times.
✗ Branch 1 not taken.
2397 sfx(scr->secretsfx);
3304
3305
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2391 times.
2397 if(scr->flags6&fTRIGGERFPERM)
3306 {
3307
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 int32_t flags_remaining = findtrigger(screen); //Normal flags
3308
3309
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (flags_remaining)
3310 {
3311
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 Z_eventlog("Hit All Triggers->Perm Secret not fulfilled (%d trigger flag%s remain).\n", flags_remaining, flags_remaining>1?"s":"");
3312 3 setflag=false;
3313 3 }
3314
3315 // Only actually trigger secrets now if 1) all triggers are gone and 2) QR qr_ALLTRIG_PERMSEC_NO_TEMP is off, in
3316 // which case only the screen state for mSECRET may be set below.
3317
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
6 if (!flags_remaining && !get_qr(qr_ALLTRIG_PERMSEC_NO_TEMP))
3318 {
3319 trigger_secrets_for_screen(TriggerSource::Unspecified, scr, scr->flags6&fTRIGGERF1631, -1);
3320 }
3321 6 }
3322
3323
5/6
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 105 times.
✓ Branch 2 taken 2292 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1108 times.
✓ Branch 5 taken 1184 times.
2397 if (setflag && canPermSecret(cur_dmap, screen))
3324
2/2
✓ Branch 0 taken 721 times.
✓ Branch 1 taken 463 times.
1905 if(!(scr->flags5&fTEMPSECRETS))
3325
1/2
✓ Branch 0 taken 721 times.
✗ Branch 1 not taken.
721 setmapflag(scr, mSECRET);
3326
3327 2397 return true;
3328 4457867 }
3329
3330 14809012 void update_slopes()
3331 {
3332
2/2
✓ Branch 0 taken 142356 times.
✓ Branch 1 taken 14809012 times.
14951368 for (auto& p : slopes)
3333 {
3334 142356 slope_object& s = p.second;
3335 142356 s.updateslope(); //sets old x/y poses
3336 }
3337 14809012 }
3338
3339 14402369 void update_freeform_combos()
3340 {
3341 14402369 ffscript_engine(false);
3342
2/2
✓ Branch 0 taken 24172 times.
✓ Branch 1 taken 14378197 times.
14402369 if ( !FFCore.system_suspend[susptUPDATEFFC] )
3343 {
3344 14378197 int wrap_right = world_w + 32;
3345 14378197 int wrap_bottom = world_h + 32;
3346
3347 485520731 for_every_ffc([&](const ffc_handle_t& ffc_handle) {
3348 471142534 mapscr* scr = ffc_handle.scr;
3349 471142534 ffcdata& thisffc = *ffc_handle.ffc;
3350
3351 // Combo 0?
3352
2/2
✓ Branch 0 taken 44992239 times.
✓ Branch 1 taken 426150295 times.
471142534 if(thisffc.data==0)
3353 426150295 return;
3354
3355 // Changer?
3356
2/2
✓ Branch 0 taken 543029 times.
✓ Branch 1 taken 44449210 times.
44992239 if(thisffc.flags&ffc_changer)
3357 543029 return;
3358
3359 // Stationary?
3360
2/2
✓ Branch 0 taken 9844 times.
✓ Branch 1 taken 44439366 times.
44449210 if(thisffc.flags&ffc_stationary)
3361 9844 return;
3362
3363 // Frozen because Hero's holding up an item?
3364
3/4
✓ Branch 0 taken 138282 times.
✓ Branch 1 taken 44301084 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 138282 times.
44439366 if(Hero.getHoldClk()>0 && (thisffc.flags&ffc_ignoreholdup)==0)
3365 138282 return;
3366
3367 // Check for changers
3368
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 if (thisffc.link==0)
3369 {
3370 442453159 for_some_ffcs([&](const ffc_handle_t& other_ffc_handle) {
3371
2/2
✓ Branch 0 taken 14755762 times.
✓ Branch 1 taken 412940099 times.
427695861 if (ffc_handle.id == other_ffc_handle.id)
3372 14755762 return true;
3373
3374 412940099 ffcdata& otherffc = *other_ffc_handle.ffc;
3375 // Combo 0?
3376
2/2
✓ Branch 0 taken 144689583 times.
✓ Branch 1 taken 268250516 times.
412940099 if(otherffc.data==0)
3377 268250516 return true;
3378
3379 // Not a changer?
3380
2/2
✓ Branch 0 taken 140701406 times.
✓ Branch 1 taken 3988177 times.
144689583 if(!(otherffc.flags&ffc_changer))
3381 140701406 return true;
3382
3383 // Ignore this changer?
3384
4/4
✓ Branch 0 taken 546579 times.
✓ Branch 1 taken 3441598 times.
✓ Branch 2 taken 299257 times.
✓ Branch 3 taken 3142341 times.
3988177 if((otherffc.x.getInt()==thisffc.changer_x&&otherffc.y.getInt()==thisffc.changer_y) || thisffc.flags&ffc_ignorechanger)
3385 845836 return true;
3386
3387
3/4
✓ Branch 0 taken 2721043 times.
✓ Branch 1 taken 421298 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3562 times.
3145903 if((isonline(thisffc.x.getZLong(), thisffc.y.getZLong(), thisffc.prev_changer_x, thisffc.prev_changer_y, otherffc.x.getZLong(), otherffc.y.getZLong()) || // Along the line, or...
3388 ( // At exactly the same position,
3389
2/2
✓ Branch 0 taken 208792 times.
✓ Branch 1 taken 2512251 times.
2721043 (thisffc.x==otherffc.x && thisffc.y==otherffc.y))
3390
2/2
✓ Branch 0 taken 2303459 times.
✓ Branch 1 taken 2512251 times.
208792 ||
3391 //or imprecision and close enough
3392
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
5024502 ( (thisffc.flags&ffc_imprecisionchanger) && ((abs(thisffc.x.getZLong() - otherffc.x.getZLong()) < 10000) && abs(thisffc.y.getZLong() - otherffc.y.getZLong()) < 10000) )
3393 )
3394 && //and...
3395
2/2
✓ Branch 0 taken 3562 times.
✓ Branch 1 taken 2721195 times.
2724757 (thisffc.prev_changer_x>-10000000 && thisffc.prev_changer_y>-10000000)) // This isn't the first frame on this screen
3396 {
3397 3562 zc_ffc_changer(thisffc, otherffc, ffc_handle.id, other_ffc_handle.id);
3398 3562 return false;
3399 }
3400
3401 2721195 return true;
3402 426679763 });
3403 14757298 }
3404
3405
2/2
✓ Branch 0 taken 29543786 times.
✓ Branch 1 taken 14757298 times.
44301084 ffcdata* linked_ffc = thisffc.link ? get_ffc_handle(thisffc.link - 1).ffc : nullptr;
3406
4/4
✓ Branch 0 taken 14757298 times.
✓ Branch 1 taken 29543786 times.
✓ Branch 2 taken 14680008 times.
✓ Branch 3 taken 14863778 times.
44301084 if (linked_ffc ? !linked_ffc->delay : !thisffc.delay)
3407 {
3408
4/4
✓ Branch 0 taken 182609 times.
✓ Branch 1 taken 14681169 times.
✓ Branch 2 taken 85331 times.
✓ Branch 3 taken 97278 times.
14863778 if(thisffc.link && (thisffc.link-1) != ffc_handle.id)
3409 {
3410 97278 thisffc.prev_changer_x = thisffc.x.getZLong();
3411 97278 thisffc.prev_changer_y = thisffc.y.getZLong();
3412 97278 thisffc.x += linked_ffc->vx;
3413 97278 thisffc.y += linked_ffc->vy;
3414 97278 }
3415 else
3416 {
3417 14766500 thisffc.prev_changer_x = thisffc.x.getZLong();
3418 14766500 thisffc.prev_changer_y = thisffc.y.getZLong();
3419 14766500 thisffc.x += thisffc.vx;
3420 14766500 thisffc.y += thisffc.vy;
3421 14766500 thisffc.vx += thisffc.ax;
3422 14766500 thisffc.vy += thisffc.ay;
3423
3424
3425
2/2
✓ Branch 0 taken 444046 times.
✓ Branch 1 taken 14322454 times.
14766500 if(get_qr(qr_OLD_FFC_SPEED_CAP))
3426 {
3427
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx>128) thisffc.vx=128;
3428
3429
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vx<-128) thisffc.vx=-128;
3430
3431
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy>128) thisffc.vy=128;
3432
3433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14322454 times.
14322454 if(thisffc.vy<-128) thisffc.vy=-128;
3434 14322454 }
3435 }
3436 14863778 }
3437 else
3438 {
3439
3/4
✓ Branch 0 taken 1161 times.
✓ Branch 1 taken 76129 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1161 times.
29437306 if(!thisffc.link || (thisffc.link-1) == ffc_handle.id)
3440 76129 thisffc.delay--;
3441 }
3442
3443 // Check if the FFC's off the side of the screen
3444
3445 // Left
3446
2/2
✓ Branch 0 taken 10449 times.
✓ Branch 1 taken 14930619 times.
14941068 if(thisffc.x<-32)
3447 {
3448
2/2
✓ Branch 0 taken 253 times.
✓ Branch 1 taken 10196 times.
10449 if(scr->flags6&fWRAPAROUNDFF)
3449 {
3450 253 thisffc.x = wrap_right+(thisffc.x+32);
3451 253 thisffc.solid_update(false);
3452 253 thisffc.prev_changer_y = thisffc.y.getZLong();
3453 // Re-enable previous changer
3454 253 thisffc.changer_x = -1000;
3455 253 thisffc.changer_y = -1000;
3456 253 }
3457
2/2
✓ Branch 0 taken 10127 times.
✓ Branch 1 taken 69 times.
10196 else if(thisffc.x<-64)
3458 {
3459 69 zc_ffc_set(thisffc, 0);
3460 69 thisffc.flags&=~ffc_carryover;
3461 69 }
3462 10449 }
3463 // Right
3464
2/2
✓ Branch 0 taken 14930438 times.
✓ Branch 1 taken 181 times.
14930619 else if(thisffc.x>=wrap_right)
3465 {
3466
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 53 times.
181 if(scr->flags6&fWRAPAROUNDFF)
3467 {
3468 128 thisffc.x = thisffc.x-wrap_right-32;
3469 128 thisffc.solid_update(false);
3470 128 thisffc.prev_changer_y = thisffc.y.getZLong();
3471 128 thisffc.changer_x = -1000;
3472 128 thisffc.changer_y = -1000;
3473 128 }
3474 else
3475 {
3476 53 zc_ffc_set(thisffc, 0);
3477 53 thisffc.flags&=~ffc_carryover;
3478 }
3479 181 }
3480
3481 // Top
3482
2/2
✓ Branch 0 taken 25480 times.
✓ Branch 1 taken 14915588 times.
14941068 if(thisffc.y<-32)
3483 {
3484
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 25472 times.
25480 if(scr->flags6&fWRAPAROUNDFF)
3485 {
3486 8 thisffc.y = wrap_bottom+(thisffc.y+32);
3487 8 thisffc.solid_update(false);
3488 8 thisffc.prev_changer_x = thisffc.x.getZLong();
3489 8 thisffc.changer_x = -1000;
3490 8 thisffc.changer_y = -1000;
3491 8 }
3492
2/2
✓ Branch 0 taken 25155 times.
✓ Branch 1 taken 317 times.
25472 else if(thisffc.y<-64)
3493 {
3494 317 zc_ffc_set(thisffc, 0);
3495 317 thisffc.flags&=~ffc_carryover;
3496 317 }
3497 25480 }
3498 // Bottom
3499
2/2
✓ Branch 0 taken 14914744 times.
✓ Branch 1 taken 844 times.
14915588 else if(thisffc.y>=wrap_bottom)
3500 {
3501
2/2
✓ Branch 0 taken 753 times.
✓ Branch 1 taken 91 times.
844 if(scr->flags6&fWRAPAROUNDFF)
3502 {
3503 753 thisffc.y = thisffc.y-wrap_bottom-32;
3504 753 thisffc.solid_update(false);
3505 753 thisffc.prev_changer_y = thisffc.x.getZLong();
3506 753 thisffc.changer_x = -1000;
3507 753 thisffc.changer_y = -1000;
3508 753 }
3509 else
3510 {
3511 91 zc_ffc_set(thisffc, 0);
3512 91 thisffc.flags&=~ffc_carryover;
3513 }
3514 844 }
3515 14941068 thisffc.solid_update();
3516 441782518 });
3517 14378197 }
3518 14402369 }
3519
3520 bool hitflag(int32_t x, int32_t y, int32_t flagtype, byte layers)
3521 {
3522 for(int q = 0; q < 7; ++q)
3523 {
3524 if(layers&(1<<q)) //if layer is to be checked
3525 if(MAPFLAG2(q-1,x,y)==flagtype||MAPCOMBOFLAG2(q-1,x,y)==flagtype) //matching flag
3526 return true;
3527 }
3528 return false;
3529 }
3530
3531 231 optional<int> nextscr(int screen, int dir)
3532 {
3533 231 auto [m, s] = nextscr2(cur_map, screen, dir);
3534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231 times.
231 if (m == -1) return nullopt;
3535 462 return (m<<7) + s;
3536 231 }
3537
3538 1058 std::pair<int32_t, int32_t> nextscr2(int32_t dir)
3539 {
3540 1058 int32_t map = cur_map;
3541
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1058 times.
1058 int32_t screen = screenscrolling ? scrolling_hero_screen : hero_screen;
3542 1058 return nextscr2(map, screen, dir);
3543 }
3544
3545 5576 std::pair<int32_t, int32_t> nextscr2(int map, int screen, int32_t dir)
3546 {
3547 5576 screen = screen_index_direction(screen, (direction)dir);
3548
3549 // need to check for screens on other maps, 's' not valid, etc.
3550 5576 int32_t index = (hero_scr->sidewarpindex >> (dir*2))&3;
3551
3552 // Fun fact: when a scrolling warp is triggered, this function
3553 // is never even called! - Saf
3554
2/2
✓ Branch 0 taken 3326 times.
✓ Branch 1 taken 2250 times.
6120 if(hero_scr->sidewarptype[index] == 3) // scrolling warp
3555 {
3556
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 482 times.
✓ Branch 2 taken 525 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 697 times.
2250 switch(dir)
3557 {
3558 case up:
3559
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 399 times.
482 if(!(hero_scr->flags2&wfUP)) goto nowarp;
3560
3561 83 break;
3562
3563 case down:
3564
2/2
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 446 times.
525 if(!(hero_scr->flags2&wfDOWN)) goto nowarp;
3565
3566 79 break;
3567
3568 case left:
3569
2/2
✓ Branch 0 taken 209 times.
✓ Branch 1 taken 337 times.
546 if(!(hero_scr->flags2&wfLEFT)) goto nowarp;
3570
3571 209 break;
3572
3573 case right:
3574
2/2
✓ Branch 0 taken 173 times.
✓ Branch 1 taken 524 times.
697 if(!(hero_scr->flags2&wfRIGHT)) goto nowarp;
3575
3576 173 break;
3577 }
3578
3579 544 map = DMaps[hero_scr->sidewarpdmap[index]].map;
3580 544 screen = hero_scr->sidewarpscr[index] + DMaps[hero_scr->sidewarpdmap[index]].xoff;
3581 544 }
3582
3583 nowarp:
3584
4/4
✓ Branch 0 taken 5512 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 112 times.
✓ Branch 3 taken 5400 times.
5576 if(screen<0||screen>=128)
3585 176 return {-1, -1};
3586
3587 5400 return {map, screen};
3588 5576 }
3589
3590 403 optional<int> nextscr_mi(int mi, int dir)
3591 {
3592 403 int map = mi/MAPSCRSNORMAL;
3593 403 int screen = mi%MAPSCRSNORMAL;
3594 403 auto [m, s] = nextscr2(map, screen, dir);
3595
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 402 times.
403 if (m == -1) return nullopt;
3596 804 return (m<<7) + s;
3597 403 }
3598
3599 2114 void bombdoor(int32_t x,int32_t y)
3600 {
3601
2/2
✓ Branch 0 taken 2094 times.
✓ Branch 1 taken 20 times.
2114 if (!is_in_world_bounds(x, y))
3602 20 return;
3603
3604 2094 auto rpos_handle = get_rpos_handle_for_world_xy(x, y, 0);
3605 2094 mapscr* scr = rpos_handle.scr;
3606 2094 int screen = scr->screen;
3607 2902 auto [x0, y0] = translate_screen_coordinates_to_world(rpos_handle.screen);
3608 #define CHECK_RECT(x,y,rx1,ry1,rx2,ry2) (isinRect(x,y,x0+rx1,y0+ry1,x0+rx2,y0+ry2))
3609
3610
12/12
✓ Branch 0 taken 79 times.
✓ Branch 1 taken 2015 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 69 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 69 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 69 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 69 times.
2094 if(scr->door[0]==dBOMB && CHECK_RECT(x,y,100,0,139,48))
3611 {
3612 69 scr->door[0]=dBOMBED;
3613 69 putdoor(scr, scrollbuf, 0, dBOMBED);
3614 69 setmapflag(scr, mDOOR_UP);
3615 69 markBmap(-1, screen);
3616
3617
1/2
✓ Branch 0 taken 69 times.
✗ Branch 1 not taken.
69 if(auto v = nextscr(screen, up))
3618 {
3619 69 setmapflag_mi(*v, mDOOR_DOWN);
3620 69 markBmap(-1,*v-(get_currdmap()<<7));
3621 69 }
3622 69 }
3623
3624
12/12
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 2045 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 39 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 39 times.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 39 times.
✓ Branch 8 taken 10 times.
✓ Branch 9 taken 39 times.
✓ Branch 10 taken 10 times.
✓ Branch 11 taken 39 times.
2094 if(scr->door[1]==dBOMB && CHECK_RECT(x,y,100,112,139,176))
3625 {
3626 39 scr->door[1]=dBOMBED;
3627 39 putdoor(scr, scrollbuf, 1, dBOMBED);
3628 39 setmapflag(scr, mDOOR_DOWN);
3629 39 markBmap(-1, rpos_handle.screen);
3630
3631
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 if(auto v = nextscr(rpos_handle.screen, down))
3632 {
3633 39 setmapflag_mi(*v, mDOOR_UP);
3634 39 markBmap(-1,*v-(get_currdmap()<<7));
3635 39 }
3636 39 }
3637
3638
12/12
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 2027 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 16 times.
✓ Branch 5 taken 51 times.
✓ Branch 6 taken 16 times.
✓ Branch 7 taken 51 times.
✓ Branch 8 taken 16 times.
✓ Branch 9 taken 51 times.
✓ Branch 10 taken 16 times.
✓ Branch 11 taken 51 times.
2094 if(scr->door[2]==dBOMB && CHECK_RECT(x,y,0,60,48,98))
3639 {
3640 51 scr->door[2]=dBOMBED;
3641 51 putdoor(scr, scrollbuf, 2, dBOMBED);
3642 51 setmapflag(scr, mDOOR_LEFT);
3643 51 markBmap(-1, rpos_handle.screen);
3644
3645
1/2
✓ Branch 0 taken 51 times.
✗ Branch 1 not taken.
51 if(auto v = nextscr(rpos_handle.screen, left))
3646 {
3647 51 setmapflag_mi(*v, mDOOR_RIGHT);
3648 51 markBmap(-1,*v-(get_currdmap()<<7));
3649 51 }
3650 51 }
3651
3652
12/12
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 2008 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 72 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 72 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 72 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 72 times.
✓ Branch 10 taken 14 times.
✓ Branch 11 taken 72 times.
2094 if(scr->door[3]==dBOMB && CHECK_RECT(x,y,192,60,240,98))
3653 {
3654 72 scr->door[3]=dBOMBED;
3655 72 putdoor(scr, scrollbuf, 3, dBOMBED);
3656 72 setmapflag(scr, mDOOR_RIGHT);
3657 72 markBmap(-1, rpos_handle.screen);
3658
3659
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 if(auto v = nextscr(rpos_handle.screen, right))
3660 {
3661 72 setmapflag_mi(*v, mDOOR_LEFT);
3662 72 markBmap(-1,*v-(get_currdmap()<<7));
3663 72 }
3664 72 }
3665 2114 }
3666
3667 6384306538 void draw_cmb(BITMAP* dest, int32_t x, int32_t y, int32_t cid, int32_t cset,
3668 bool over, bool transp)
3669 {
3670 6384306538 auto& cmb = combobuf[cid];
3671
2/2
✓ Branch 0 taken 90743 times.
✓ Branch 1 taken 6384215795 times.
6384306538 if(cmb.animflags & AF_EDITOR_ONLY)
3672 90743 return;
3673
2/2
✓ Branch 0 taken 3309354865 times.
✓ Branch 1 taken 3074860930 times.
6384215795 if(over)
3674 {
3675
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3309354865 times.
3309354865 if(cmb.animflags & AF_TRANSPARENT)
3676 transp = !transp;
3677
2/2
✓ Branch 0 taken 319148412 times.
✓ Branch 1 taken 2990206453 times.
3309354865 if(transp)
3678 319148412 overcombotranslucent(dest, x, y, cid, cset, 128);
3679 2990206453 else overcombo(dest, x, y, cid, cset);
3680 3309354865 }
3681 3074860930 else putcombo(dest, x, y, cid, cset);
3682 6384306538 }
3683 6384314986 void draw_cmb_pos(BITMAP* dest, int32_t x, int32_t y, rpos_t rpos, int32_t cid,
3684 int32_t cset, byte layer, bool over, bool transp)
3685 {
3686
2/2
✓ Branch 0 taken 750736355 times.
✓ Branch 1 taken 5633578631 times.
6384314986 if (rpos != rpos_t::None)
3687 {
3688 5633578631 rpos_t plrpos = COMBOPOS_REGION_B(Hero.x+8, Hero.y+8);
3689
2/2
✓ Branch 0 taken 749524 times.
✓ Branch 1 taken 5632829107 times.
5633578631 if (plrpos != rpos_t::None)
3690 {
3691 5632829107 bool dosw = false;
3692
4/4
✓ Branch 0 taken 52860 times.
✓ Branch 1 taken 5632776247 times.
✓ Branch 2 taken 44412 times.
✓ Branch 3 taken 8448 times.
5632829107 if (rpos == hooked_comborpos && (hooked_layerbits & (1<<layer)))
3693 {
3694
1/2
✓ Branch 0 taken 8448 times.
✗ Branch 1 not taken.
8448 if(hooked_undercombos[layer] > -1)
3695 {
3696 draw_cmb(dest, x, y,
3697 hooked_undercombos[layer], hooked_undercombos[layer+7], over, transp);
3698 }
3699 8448 dosw = true;
3700 8448 }
3701
4/4
✓ Branch 0 taken 31973777 times.
✓ Branch 1 taken 5600846882 times.
✓ Branch 2 taken 8448 times.
✓ Branch 3 taken 31965329 times.
5632820659 else if (rpos == plrpos && (hooked_layerbits & (1<<(layer+8))))
3702 {
3703 8448 dosw = true;
3704 8448 }
3705
2/2
✓ Branch 0 taken 5632812211 times.
✓ Branch 1 taken 16896 times.
5632829107 if (dosw)
3706 {
3707
1/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 16896 times.
✗ Branch 3 not taken.
16896 switch (Hero.switchhookstyle)
3708 {
3709 default: case swPOOF:
3710 break; //Nothing special here
3711 case swFLICKER:
3712 {
3713
2/2
✓ Branch 0 taken 8448 times.
✓ Branch 1 taken 8448 times.
16896 if(abs(Hero.switchhookclk-33)&0b1000)
3714 8448 break; //Drawn this frame
3715 8448 return; //Not drawn this frame
3716 }
3717 case swRISE:
3718 {
3719 //Draw rising up
3720 y -= 8-(abs(Hero.switchhookclk-32)/4);
3721 break;
3722 }
3723 }
3724 8448 }
3725 5632820659 }
3726 5633570183 }
3727
3728 6384306538 draw_cmb(dest, x, y, cid, cset, over, transp);
3729 6384314986 }
3730
3731 // `draw_cmb_pos` only does meaningful work if the combo being drawn is within the bounds of
3732 // the `bmp` bitmap. However, even getting to the point where `puttile16` (for example) knows
3733 // to cull is somewhat expensive. Since it can only draw 16x16 pixels, we can do the equivalent
3734 // culling here by determining the rows/columns that are within the bitmap bounds. This nets
3735 // on the order of ~30 FPS in uncapped mode on my machine, depending on the viewport/region size.
3736 //
3737 // These two inequalities must be true for `draw_cmb_pos` to do anything useful:
3738 //
3739 // -16 < comboPositionX*16 + x < bitmapWidth
3740 // -16 < comboPositionY*16 + y < bitmapHeight
3741 //
3742 // The following start/end values are derived directly from the above.
3743 //
3744 // `x` and `y` are the offsets the combos will be drawn into the bitmap.
3745 39481806 static void get_bounds_for_draw_cmb_calls(BITMAP* bmp, int x, int y, int& start_x, int& end_x, int& start_y, int& end_y)
3746 {
3747 // if (bmp->clip)
3748 // {
3749 // start_x = MAX(0, ceil((bmp->cl - 15 - x) / 16.0));
3750 // end_x = MIN(16, ceil((bmp->cr - x) / 16.0));
3751 // start_y = MAX(0, ceil((bmp->ct - 15 - y) / 16.0));
3752 // end_y = MIN(11, ceil((bmp->cb - y) / 16.0));
3753 // return;
3754 // }
3755
3756
2/2
✓ Branch 0 taken 2169310 times.
✓ Branch 1 taken 37312496 times.
39481806 start_x = MAX(0, ceil((-15 - x) / 16.0));
3757
2/2
✓ Branch 0 taken 2178501 times.
✓ Branch 1 taken 37303305 times.
39481806 end_x = MIN(16, ceil((bmp->w - x) / 16.0));
3758
2/2
✓ Branch 0 taken 38092548 times.
✓ Branch 1 taken 1389258 times.
39481806 start_y = MAX(0, ceil((-15 - y) / 16.0));
3759
2/2
✓ Branch 0 taken 1678576 times.
✓ Branch 1 taken 37803230 times.
39481806 end_y = MIN(11, ceil((bmp->h - y) / 16.0));
3760 39481806 }
3761
3762 186960519 void do_ffc_layer(BITMAP* bmp, int32_t layer, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3763 {
3764
1/2
✓ Branch 0 taken 186960519 times.
✗ Branch 1 not taken.
186960519 if(!show_ffcs) return;
3765 186960519 mapscr* scr = screen_handle.scr;
3766 186960519 mapscr* base_scr = screen_handle.base_scr;
3767
3768 186960519 y += playing_field_offset;
3769
3770 186960519 bool is_bg_layer = layer < -1;
3771
2/2
✓ Branch 0 taken 33926573 times.
✓ Branch 1 taken 153033946 times.
186960519 int real_layer = is_bg_layer ? abs(layer) : layer;
3772
2/2
✓ Branch 0 taken 186960519 times.
✓ Branch 1 taken 5581189773 times.
5768150292 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3773 {
3774
2/2
✓ Branch 0 taken 5375692187 times.
✓ Branch 1 taken 205497586 times.
5581189773 if (base_scr->ffcs[i].data == 0)
3775 5375692187 continue;
3776
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 168136644 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
205497586 if(real_layer == 2 && (is_bg_layer != XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG)))
3777 18677990 continue;
3778
4/4
✓ Branch 0 taken 37360942 times.
✓ Branch 1 taken 149458654 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 18677990 times.
186819596 else if (real_layer == 3 && (is_bg_layer != XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)))
3779 18677990 continue;
3780
4/4
✓ Branch 0 taken 149463616 times.
✓ Branch 1 taken 18677990 times.
✓ Branch 2 taken 18682952 times.
✓ Branch 3 taken 130780664 times.
168141606 if (real_layer > -1 && base_scr->ffcs[i].layer != real_layer)
3781 130780664 continue;
3782
3783
6/6
✓ Branch 0 taken 3008970 times.
✓ Branch 1 taken 34351972 times.
✓ Branch 2 taken 5110 times.
✓ Branch 3 taken 3003860 times.
✓ Branch 4 taken 2626 times.
✓ Branch 5 taken 2484 times.
37360942 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3784 2484 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3785
3786 37358458 base_scr->ffcs[i].draw_ffc(bmp, x, y, (layer==-1));
3787 37358458 }
3788 186960519 }
3789 170937415 void _do_current_ffc_layer(BITMAP* bmp, int32_t layer)
3790 {
3791
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 170937415 times.
170937415 if(!show_ffcs) return;
3792 346453052 for_every_base_screen_in_region([&](mapscr* base_scr, unsigned int region_scr_x, unsigned int region_scr_y) {
3793 175515637 screen_handle_t handle = {base_scr, base_scr, base_scr->screen, 0};
3794 175515637 do_ffc_layer(bmp, layer, handle, 0, 0);
3795 175515637 });
3796 170937415 }
3797 75616832 void do_scrolling_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3798 {
3799 75616832 mapscr* scr = screen_handle.scr;
3800 75616832 mapscr* base_scr = screen_handle.base_scr;
3801
3802
4/4
✓ Branch 0 taken 60951502 times.
✓ Branch 1 taken 14665330 times.
✓ Branch 2 taken 14665330 times.
✓ Branch 3 taken 75616832 times.
75616832 if (type == -3 || type == -4)
3803 {
3804 29330660 y += playing_field_offset;
3805
3806
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
29330660 for(int32_t i = (base_scr->numFFC()-1); i >= 0; --i)
3807 {
3808 if (base_scr->ffcs[i].data == 0)
3809 continue;
3810
3811 if (screenscrolling && (base_scr->ffcs[i].flags & ffc_carryover) != 0 && screen_handle.screen != scrolling_hero_screen)
3812 continue; //If scrolling, only draw carryover ffcs from newscr and not oldscr.
3813
3814 base_scr->ffcs[i].draw_ffc(bmp, x, y, (type==-4));
3815 }
3816 return;
3817 }
3818
3819 75616832 x -= viewport.x;
3820 75616832 y -= viewport.y - playing_field_offset;
3821
3822 75616832 bool over = true, transp = false;
3823 75616832 int layer = screen_handle.layer;
3824
3825
7/8
✓ Branch 0 taken 55151077 times.
✓ Branch 1 taken 20465755 times.
✓ Branch 2 taken 13148696 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34185284 times.
✓ Branch 5 taken 20965793 times.
✓ Branch 6 taken 3060005 times.
✓ Branch 7 taken 4257054 times.
75616832 switch(type ? type : layer)
3826 {
3827 case -2: //push blocks
3828
2/2
✓ Branch 0 taken 19519954 times.
✓ Branch 1 taken 14665330 times.
34185284 if (scr)
3829 {
3830
2/2
✓ Branch 0 taken 3435511904 times.
✓ Branch 1 taken 23710596 times.
3435005872 for(int32_t i=0; i<176; i++)
3831 {
3832 3435511904 int32_t mf=scr->sflag[i], mf2 = combobuf[scr->data[i]].flag;
3833
3834
10/10
✓ Branch 0 taken 3435341560 times.
✓ Branch 1 taken 170344 times.
✓ Branch 2 taken 3433869588 times.
✓ Branch 3 taken 1471972 times.
✓ Branch 4 taken 3433240605 times.
✓ Branch 5 taken 628983 times.
✓ Branch 6 taken 24420859 times.
✓ Branch 7 taken 3408819746 times.
✓ Branch 8 taken 42762999 times.
✓ Branch 9 taken 16705821 times.
3472559372 if(mf==mfPUSHUD || mf==mfPUSH4 || mf==mfPUSHED || ((mf>=mfPUSHLR)&&(mf<=mfPUSHRINS))
3835
6/8
✓ Branch 0 taken 3430359076 times.
✓ Branch 1 taken 21539330 times.
✓ Branch 2 taken 3430359076 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3430359076 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 37047468 times.
✓ Branch 7 taken 3393311608 times.
3433240605 || mf2==mfPUSHUD || mf2==mfPUSH4 || mf2==mfPUSHED || ((mf2>=mfPUSHLR)&&(mf2<=mfPUSHRINS)))
3836 {
3837
4/4
✓ Branch 0 taken 4772507 times.
✓ Branch 1 taken 695982 times.
✓ Branch 2 taken 3657 times.
✓ Branch 3 taken 4768850 times.
90994487 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3838 5468489 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3839 5468489 }
3840 3415485918 }
3841 23710596 }
3842 38375926 return;
3843
3844 case -1: //over combo
3845
1/2
✓ Branch 0 taken 20965793 times.
✗ Branch 1 not taken.
20965793 if (scr)
3846 {
3847
2/2
✓ Branch 0 taken 3689979568 times.
✓ Branch 1 taken 20965793 times.
3710945361 for(int32_t i=0; i<176; i++)
3848 {
3849
2/2
✓ Branch 0 taken 3670703512 times.
✓ Branch 1 taken 19276056 times.
3689979568 if(combo_class_buf[combobuf[scr->data[i]].type].overhead)
3850 {
3851
4/4
✓ Branch 0 taken 15523213 times.
✓ Branch 1 taken 3752843 times.
✓ Branch 2 taken 22320 times.
✓ Branch 3 taken 15500893 times.
19276056 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3852 19276056 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, true, false);
3853 19276056 }
3854 3689979568 }
3855 20965793 }
3856 20965793 return;
3857
3858 case 1:
3859 case 4:
3860 case 5:
3861 case 6:
3862
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 13148696 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
13148696 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3863 {
3864
1/2
✓ Branch 0 taken 13148696 times.
✗ Branch 1 not taken.
13148696 if (scr)
3865 {
3866
2/2
✓ Branch 0 taken 11489485 times.
✓ Branch 1 taken 1659211 times.
13148696 if(base_scr->layeropacity[layer-1]!=255)
3867 1659211 transp = true;
3868 13148696 break;
3869 }
3870 }
3871 return;
3872
3873 case 2:
3874
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 3060005 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
3060005 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3875 {
3876
1/2
✓ Branch 0 taken 3060005 times.
✗ Branch 1 not taken.
3060005 if (scr)
3877 {
3878
2/2
✓ Branch 0 taken 2840408 times.
✓ Branch 1 taken 219597 times.
3060005 if(base_scr->layeropacity[layer-1]!=255)
3879 219597 transp = true;
3880
3881
2/2
✓ Branch 0 taken 2931096 times.
✓ Branch 1 taken 128909 times.
3060005 if(XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3882 128909 over = false;
3883
3884 3060005 break;
3885 }
3886 }
3887 return;
3888
3889 case 3:
3890
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 4257054 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
4257054 if(TransLayers || base_scr->layeropacity[layer-1]==255)
3891 {
3892
1/2
✓ Branch 0 taken 4257054 times.
✗ Branch 1 not taken.
4257054 if (scr)
3893 {
3894
2/2
✓ Branch 0 taken 4183341 times.
✓ Branch 1 taken 73713 times.
4257054 if(base_scr->layeropacity[layer-1]!=255)
3895 73713 transp = true;
3896
3897
2/2
✓ Branch 0 taken 36654 times.
✓ Branch 1 taken 60483 times.
4257054 if(XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG)
3898
2/2
✓ Branch 0 taken 97137 times.
✓ Branch 1 taken 4159917 times.
4257054 && !XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
3899 60483 over = false;
3900
3901 4257054 break;
3902 }
3903 }
3904 return;
3905 }
3906
3907 int start_x, end_x, start_y, end_y;
3908 20465755 get_bounds_for_draw_cmb_calls(bmp, x, y, start_x, end_x, start_y, end_y);
3909
2/2
✓ Branch 0 taken 20465755 times.
✓ Branch 1 taken 216989831 times.
237455586 for (int cy = start_y; cy < end_y; cy++)
3910 {
3911
2/2
✓ Branch 0 taken 3283735479 times.
✓ Branch 1 taken 216989831 times.
3500725310 for (int cx = start_x; cx < end_x; cx++)
3912 {
3913 3283735479 int i = cx + cy*16;
3914
4/4
✓ Branch 0 taken 2905552252 times.
✓ Branch 1 taken 378183227 times.
✓ Branch 2 taken 10227360 times.
✓ Branch 3 taken 2895324892 times.
3283735479 auto rpos = screenscrolling || ViewingMap ? rpos_t::None : POS_TO_RPOS(i, screen_handle.screen);
3915 3283735479 draw_cmb_pos(bmp, x + COMBOX(i), y + COMBOY(i), rpos, scr->data[i], scr->cset[i], layer, over, transp);
3916 3283735479 }
3917 216989831 }
3918 60951502 }
3919
3920 269002203 bool lenscheck(mapscr* scr, int layer)
3921 {
3922
4/4
✓ Branch 0 taken 268823255 times.
✓ Branch 1 taken 178948 times.
✓ Branch 2 taken 178948 times.
✓ Branch 3 taken 269002203 times.
269002203 if(layer < 0 || layer > 6) return true;
3923
2/2
✓ Branch 0 taken 259588626 times.
✓ Branch 1 taken 9413577 times.
269002203 if(get_qr(qr_OLD_LENS_LAYEREFFECT))
3924 {
3925
2/2
✓ Branch 0 taken 209710465 times.
✓ Branch 1 taken 49878161 times.
259588626 if(!layer) return true;
3926
8/8
✓ Branch 0 taken 34922371 times.
✓ Branch 1 taken 174788094 times.
✓ Branch 2 taken 258970 times.
✓ Branch 3 taken 34663401 times.
✓ Branch 4 taken 143758 times.
✓ Branch 5 taken 163336 times.
✓ Branch 6 taken 326536 times.
✓ Branch 7 taken 34480623 times.
209710465 if((layer==(int32_t)(scr->lens_layer&7)+1) && ((scr->lens_layer&llLENSSHOWS && !lensclk) || (scr->lens_layer&llLENSHIDES && lensclk)))
3927 489872 return false;
3928 209268717 }
3929 else
3930 {
3931
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 9413577 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 9413577 times.
9413577 if((lensclk ? scr->lens_hide : scr->lens_show) & (1<<layer))
3932 return false;
3933 }
3934 218682294 return true;
3935 268823255 }
3936
3937 156158207 void do_layer(BITMAP *bmp, int32_t type, const screen_handle_t& screen_handle, int32_t x, int32_t y)
3938 {
3939 156158207 bool showlayer = true;
3940 156158207 mapscr* base_scr = screen_handle.base_scr;
3941 156158207 int layer = screen_handle.layer;
3942
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 int target = type ? type : layer;
3943
3/4
✓ Branch 0 taken 114073758 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20230988 times.
✓ Branch 3 taken 21853461 times.
156158207 switch(target)
3944 {
3945 case -2:
3946
1/2
✓ Branch 0 taken 20230988 times.
✗ Branch 1 not taken.
20230988 if(!show_layer_push)
3947 showlayer = false;
3948 20230988 break;
3949
3950 case -1:
3951
1/2
✓ Branch 0 taken 21853461 times.
✗ Branch 1 not taken.
21853461 if(!show_layer_over)
3952 showlayer = false;
3953 21853461 break;
3954
3955 case 1: case 2: case 3:
3956 case 4: case 5: case 6:
3957 114073758 showlayer = show_layers[target];
3958 114073758 break;
3959 }
3960
3961
2/2
✓ Branch 0 taken 42084449 times.
✓ Branch 1 taken 114073758 times.
156158207 if(!type)
3962 {
3963
2/2
✓ Branch 0 taken 113937560 times.
✓ Branch 1 taken 136198 times.
114073758 if(!lenscheck(base_scr,layer))
3964 136198 showlayer = false;
3965 114073758 }
3966
3967
2/2
✓ Branch 0 taken 136198 times.
✓ Branch 1 taken 156022009 times.
156158207 if(showlayer)
3968 {
3969
6/6
✓ Branch 0 taken 61007625 times.
✓ Branch 1 taken 95014384 times.
✓ Branch 2 taken 20521878 times.
✓ Branch 3 taken 40485747 times.
✓ Branch 4 taken 56123 times.
✓ Branch 5 taken 20465755 times.
156022009 if (screen_handle.scr && (type || !(base_scr->hidelayers & (1 << (layer)))))
3970 {
3971 60951502 do_scrolling_layer(bmp, type, screen_handle, x, y);
3972
4/4
✓ Branch 0 taken 20465755 times.
✓ Branch 1 taken 40485747 times.
✓ Branch 2 taken 19233761 times.
✓ Branch 3 taken 1231994 times.
60951502 if(!type && !get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
3973
2/2
✓ Branch 0 taken 1231418 times.
✓ Branch 1 taken 576 times.
1232570 if(mblock2.draw(bmp,layer))
3974 576 do_primitives(bmp, SPLAYER_MOVINGBLOCK);
3975 60951502 }
3976 156022009 }
3977 156158207 }
3978
3979 103025421 void do_layer_primitives(BITMAP *bmp, int32_t layer)
3980 {
3981 103025421 bool showlayer = true;
3982
3983
2/4
✓ Branch 0 taken 103025421 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 103025421 times.
103025421 if(layer >= 0 && layer <= 6)
3984 {
3985 103025421 showlayer = show_layers[layer];
3986
3987
2/2
✓ Branch 0 taken 102898819 times.
✓ Branch 1 taken 126602 times.
103025421 if(!lenscheck(origin_scr,layer))
3988 126602 showlayer = false;
3989 103025421 }
3990
3991
2/2
✓ Branch 0 taken 126602 times.
✓ Branch 1 taken 102898819 times.
103025421 if (showlayer)
3992 102898819 do_primitives(bmp, layer);
3993 103025421 }
3994
3995 // Called by do_walkflags
3996 void put_walkflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
3997 {
3998 newcombo const &c = combobuf[cmbdat];
3999
4000 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4001
4002 int32_t xx = x-xofs;
4003 int32_t yy = y+playing_field_offset-yofs;
4004
4005 int32_t bridgedetected = 0;
4006
4007 for(int32_t i=0; i<4; i++)
4008 {
4009 int32_t tx=((i&2)<<2)+xx - viewport.x;
4010 int32_t ty=((i&1)<<3)+yy - viewport.y;
4011 int32_t tx2=((i&2)<<2)+x - viewport.x;
4012 int32_t ty2=((i&1)<<3)+y - viewport.y;
4013 for (int32_t j = lyr-1; j <= 1; j++)
4014 {
4015 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4016 {
4017 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && !_walkflag_layer(tx2,ty2,j))
4018 {
4019 bridgedetected |= (1<<i);
4020 }
4021 }
4022 else
4023 {
4024 if (combobuf[MAPCOMBO2(j,tx2,ty2)].type == cBRIDGE && _effectflag_layer(tx2,ty2,j))
4025 {
4026 bridgedetected |= (1<<i);
4027 }
4028 }
4029 }
4030 if ((bridgedetected & (1<<i)))
4031 {
4032 if (i >= 3) break;
4033 else continue;
4034 }
4035 bool doladdercheck = true;
4036
4037 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4038 {
4039 for(int32_t k=0; k<8; k+=2)
4040 for(int32_t j=0; j<8; j+=2)
4041 if(((k+j)/2)%2)
4042 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,makecol(85,85,255));
4043 }
4044 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4045 {
4046 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4047 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4048 rectfill(dest,tx,ty,tx+7,ty+7,makecol(85,85,255));
4049 else rectfill(dest,tx,ty,tx+7,ty+7,makecol(170,170,170));
4050 }
4051
4052 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4053 {
4054 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4055 {
4056 for(int32_t k=0; k<8; k+=2)
4057 for(int32_t j=0; j<8; j+=2)
4058 rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,((k+j)/2)%2 ? makecol(165,105,8) : makecol(170,170,170));
4059 }
4060 else
4061 {
4062 int32_t color = makecol(178,36,36);
4063
4064 if(isstepable(cmbdat)&& (!doladdercheck))
4065 color=makecol(165,105,8);
4066 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4067 color=makecol(170,170,170);
4068
4069 rectfill(dest,tx,ty,tx+7,ty+7,color);
4070 }
4071 }
4072 }
4073
4074 // Draw damage combos
4075 bool dmg = combo_class_buf[combobuf[MAPCOMBO2(-1,xx,yy)].type].modify_hp_amount
4076 || combo_class_buf[combobuf[MAPCOMBO2(0,xx,yy)].type].modify_hp_amount
4077 || combo_class_buf[combobuf[MAPCOMBO2(1,xx,yy)].type].modify_hp_amount;
4078
4079 if(dmg)
4080 {
4081 int32_t color = makecol(255,255,0);
4082 if (bridgedetected <= 0)
4083 {
4084 for(int32_t k=0; k<16; k+=2)
4085 for(int32_t j=0; j<16; j+=2)
4086 if(((k+j)/2)%2)
4087 {
4088 int32_t x0 = x - viewport.x;
4089 int32_t y0 = y - viewport.y;
4090 rectfill(dest,x0+k,y0+j,x0+k+1,y0+j+1,color);
4091 }
4092 }
4093 else
4094 {
4095 for(int32_t i=0; i<4; i++)
4096 {
4097 if (!(bridgedetected & (1<<i)))
4098 {
4099 int32_t tx=((i&2)<<2)+x - viewport.x;
4100 int32_t ty=((i&1)<<3)+y - viewport.y;
4101 for(int32_t k=0; k<8; k+=2)
4102 for(int32_t j=0; j<8; j+=2)
4103 if((k+j)%4 < 2) rectfill(dest,tx+k,ty+j,tx+k+1,ty+j+1,color);
4104 }
4105 }
4106 }
4107 }
4108 }
4109 static void put_walkflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4110 {
4111 ALLEGRO_COLOR col_solid = al_map_rgba(178,36,36,info_opacity);
4112 ALLEGRO_COLOR col_water1 = al_map_rgba(85,85,255,info_opacity);
4113 ALLEGRO_COLOR col_lhook = al_map_rgba(170,170,170,info_opacity);
4114 ALLEGRO_COLOR col_stepable = al_map_rgba(165,105,8,info_opacity);
4115 ALLEGRO_COLOR col_dmg = al_map_rgba(255,255,0,info_opacity);
4116 newcombo const &c = combobuf[cmbdat];
4117
4118 if (c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) return;
4119
4120 int32_t xx = x-viewport.x;
4121 int32_t yy = y+playing_field_offset-viewport.y;
4122
4123 int32_t bridgedetected = 0;
4124
4125 // Draw damage combos
4126 bool dmg = combo_class_buf[c.type].modify_hp_amount;
4127
4128 for(int32_t i=0; i<4; i++)
4129 {
4130 int32_t tx=((i&2)<<2)+xx;
4131 int32_t ty=((i&1)<<3)+yy;
4132 int32_t tx2=((i&2)<<2)+x;
4133 int32_t ty2=((i&1)<<3)+y;
4134 for (int32_t m = lyr-1; m <= 1; m++)
4135 {
4136 if (get_qr(qr_OLD_BRIDGE_COMBOS))
4137 {
4138 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && !_walkflag_layer(tx2, ty2, m))
4139 {
4140 bridgedetected |= (1<<i);
4141 }
4142 }
4143 else
4144 {
4145 if (m >= 0 && combobuf[MAPCOMBO2(m, tx2, ty2)].type == cBRIDGE && _effectflag_layer(tx2, ty2, m))
4146 {
4147 bridgedetected |= (1<<i);
4148 }
4149 }
4150 }
4151 if ((bridgedetected & (1<<i)))
4152 continue;
4153 bool doladdercheck = true;
4154
4155 if ((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag4)) && c.type == cWATER) || c.type == cSHALLOWWATER))
4156 {
4157 for(int32_t k=0; k<8; k+=2)
4158 for(int32_t j=0; j<8; j+=2)
4159 if(((k+j)/2)%2)
4160 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_water1);
4161 }
4162 if (iswater_type(c.type) && !DRIEDLAKE && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) //Yes, I realize this is horribly inaccurate; the alternative is the game chugging every time you turn on walk cheats.
4163 {
4164 if (get_qr(qr_NO_SOLID_SWIM)) doladdercheck = false;
4165 if((lyr==0 || (get_qr(qr_WATER_ON_LAYER_1) && lyr == 1) || (get_qr(qr_WATER_ON_LAYER_2) && lyr == 2)) && get_qr(qr_DROWN))
4166 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_water1);
4167 else al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_lhook);
4168 }
4169
4170 if(c.walk&(1<<i) && !(iswater_type(c.type) && DRIEDLAKE) && !((c.walk&(1<<(i+4))) && ((c.walk&(1<<i) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)) && c.type == cWATER)))) // Check for dried lake (watertype && not water)
4171 {
4172 if(c.type==cLADDERHOOKSHOT && isstepable(cmbdat) && ishookshottable(xx,yy))
4173 {
4174 for(int32_t k=0; k<8; k+=2)
4175 for(int32_t j=0; j<8; j+=2)
4176 al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,((k+j)/2)%2 ? col_stepable : col_lhook);
4177 }
4178 else
4179 {
4180 ALLEGRO_COLOR* color = &col_solid;
4181
4182 if(isstepable(cmbdat)&& (!doladdercheck))
4183 color=&col_stepable;
4184 else if((c.type==cHOOKSHOTONLY || c.type==cLADDERHOOKSHOT) && ishookshottable(xx,yy))
4185 color=&col_lhook;
4186
4187 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,*color);
4188 }
4189 }
4190
4191 if(dmg)
4192 {
4193 for(int32_t k=0; k<8; k+=2)
4194 for(int32_t j=0; j<8; j+=2)
4195 if((k+j)%4 < 2) al_draw_filled_rectangle(tx+k,ty+j,tx+k+2,ty+j+2,col_dmg);
4196 }
4197 }
4198 }
4199
4200 void put_effectflags(BITMAP *dest,int32_t x,int32_t y,int32_t xofs,int32_t yofs, word cmbdat,int32_t lyr)
4201 {
4202 newcombo const &c = combobuf[cmbdat];
4203
4204 int32_t xx = x-xofs-viewport.x;
4205 int32_t yy = y+playing_field_offset-yofs-viewport.y;
4206
4207 for(int32_t i=0; i<4; i++)
4208 {
4209 int32_t tx=((i&2)<<2)+xx;
4210 int32_t ty=((i&1)<<3)+yy;
4211
4212 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4213 {
4214 int32_t color = vc(10);
4215
4216 rectfill(dest,tx,ty,tx+7,ty+7,color);
4217 }
4218 }
4219 }
4220 static void put_effectflags_a5(int32_t x, int32_t y, word cmbdat, int32_t lyr)
4221 {
4222 ALLEGRO_COLOR col_eff = al_map_rgba(85,255,85,info_opacity);
4223 newcombo const &c = combobuf[cmbdat];
4224
4225 int32_t xx = x-viewport.x;
4226 int32_t yy = y+playing_field_offset-viewport.y;
4227
4228 for(int32_t i=0; i<4; i++)
4229 {
4230 int32_t tx=((i&2)<<2)+xx;
4231 int32_t ty=((i&1)<<3)+yy;
4232
4233 if(((c.walk>>4)&(1<<i)) && c.type != cNONE)
4234 {
4235 al_draw_filled_rectangle(tx,ty,tx+8,ty+8,col_eff);
4236 }
4237 }
4238 }
4239
4240 void draw_ladder_platform(BITMAP* dest, int32_t x, int32_t y, int32_t c)
4241 {
4242 for(auto cx = 0; cx < 256; cx += 16)
4243 {
4244 for(auto cy = 0; cy < 176; cy += 16)
4245 {
4246 if(isSVLadder(cx,cy))
4247 {
4248 auto nx = cx+x, ny = cy+y;
4249 if(cy && !isSVLadder(cx,cy-16))
4250 line(dest,nx,ny,nx+15,ny,c);
4251 rectfill(dest,nx,ny,nx+3,ny+15,c);
4252 rectfill(dest,nx+12,ny,nx+15,ny+15,c);
4253 rectfill(dest,nx+4,ny+2,nx+11,ny+5,c);
4254 rectfill(dest,nx+4,ny+10,nx+11,ny+13,c);
4255 }
4256 else if(isSVPlatform(cx,cy))
4257 {
4258 line(dest,cx+x,cy+y,cx+x+15,cy+y,c);
4259 }
4260 }
4261 }
4262 }
4263 void draw_ladder_platform_a5(int32_t x, int32_t y, ALLEGRO_COLOR c)
4264 {
4265 for(auto cx = 0; cx < 256; cx += 16)
4266 {
4267 for(auto cy = 0; cy < 176; cy += 16)
4268 {
4269 if(isSVLadder(cx,cy))
4270 {
4271 auto nx = cx+x, ny = cy+y;
4272 if(cy && !isSVLadder(cx,cy-16))
4273 al_draw_line(nx,ny,nx+15,ny,c,1);
4274 al_draw_filled_rectangle(nx,ny,nx+4,ny+16,c);
4275 al_draw_filled_rectangle(nx+12,ny,nx+16,ny+16,c);
4276 al_draw_filled_rectangle(nx+4,ny+2,nx+12,ny+6,c);
4277 al_draw_filled_rectangle(nx+4,ny+10,nx+12,ny+14,c);
4278 }
4279 else if(isSVPlatform(cx,cy))
4280 {
4281 al_draw_line(cx+x,cy+y,cx+x+15,cy+y,c,1);
4282 }
4283 }
4284 }
4285 }
4286
4287 // Walkflags L4 cheat
4288 void do_walkflags(const screen_handles_t& screen_handles, int32_t x, int32_t y)
4289 {
4290 if (!show_walkflags)
4291 return;
4292
4293 start_info_bmp();
4294
4295 mapscr* scr = screen_handles[0].scr;
4296 for(int32_t i=0; i<176; i++)
4297 {
4298 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4299 }
4300
4301 for(int32_t k=0; k<2; k++)
4302 {
4303 scr = screen_handles[k + 1].scr;
4304
4305 if (scr)
4306 {
4307 for(int32_t i=0; i<176; i++)
4308 {
4309 put_walkflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], k%2+1);
4310 }
4311 }
4312 }
4313
4314 end_info_bmp();
4315 }
4316
4317 void do_walkflags(int32_t x, int32_t y)
4318 {
4319 if (!show_walkflags)
4320 return;
4321
4322 x += -viewport.x;
4323 y += playing_field_offset - viewport.y;
4324
4325 start_info_bmp();
4326
4327 draw_ladder_platform_a5(x,y,al_map_rgba(165,105,8,info_opacity));
4328 draw_solid_objects_a5(x,y,al_map_rgba(178,36,36,info_opacity));
4329 draw_slopes_a5(x,y,al_map_rgba(255,85,255,info_opacity));
4330
4331 end_info_bmp();
4332 }
4333
4334 // Effectflags L4 cheat
4335 void do_effectflags(mapscr* scr, int32_t x, int32_t y)
4336 {
4337 if(show_effectflags)
4338 {
4339 start_info_bmp();
4340
4341 for(int32_t i=0; i<176; i++)
4342 {
4343 put_effectflags_a5(((i&15)<<4) + x, (i&0xF0) + y, scr->data[i], 0);
4344 }
4345
4346 end_info_bmp();
4347 }
4348 }
4349
4350 272141 void calc_darkroom_combos(mapscr* scr, int offx, int offy)
4351 {
4352 272141 int map = scr->map;
4353 272141 int screen = scr->screen;
4354
4355
2/2
✓ Branch 0 taken 1904987 times.
✓ Branch 1 taken 272141 times.
2177128 for(int32_t lyr = 0; lyr < 7; ++lyr)
4356 {
4357 1904987 mapscr* scr = get_scr_layer(map, screen, lyr);
4358
2/2
✓ Branch 0 taken 780869 times.
✓ Branch 1 taken 1124118 times.
1904987 if (!scr->is_valid()) continue;
4359
4360
2/2
✓ Branch 0 taken 137432944 times.
✓ Branch 1 taken 780869 times.
138213813 for(int32_t q = 0; q < 176; ++q)
4361 {
4362 137432944 newcombo const& cmb = combobuf[scr->data[q]];
4363
2/2
✓ Branch 0 taken 136828325 times.
✓ Branch 1 taken 604619 times.
137432944 if(cmb.type == cTORCH)
4364 {
4365 604619 do_torch_combo(cmb, COMBOX(q)+8+offx, COMBOY(q)+8+offy, darkscr_bmp);
4366 604619 }
4367 137432944 }
4368 780869 }
4369 272141 }
4370
4371 272141 void calc_darkroom_ffcs(mapscr* scr, int offx, int offy)
4372 {
4373 272141 word c = scr->numFFC();
4374
2/2
✓ Branch 0 taken 537406 times.
✓ Branch 1 taken 272141 times.
809547 for(int q = 0; q < c; ++q)
4375 {
4376 537406 newcombo const& cmb = combobuf[scr->ffcs[q].data];
4377
2/2
✓ Branch 0 taken 522598 times.
✓ Branch 1 taken 14808 times.
537406 if(cmb.type == cTORCH)
4378 {
4379 14808 int cx = scr->ffcs[q].x.getInt()+(scr->ffEffectWidth(q)/2)+offx;
4380 14808 int cy = (scr->ffcs[q].y.getInt())+(scr->ffEffectHeight(q)/2)+offy;
4381 14808 do_torch_combo(cmb, cx, cy, darkscr_bmp);
4382 14808 }
4383 537406 }
4384 272141 }
4385
4386 struct nearby_screen_t
4387 {
4388 int screen;
4389 int offx;
4390 int offy;
4391 screen_handles_t screen_handles;
4392 };
4393 typedef std::vector<nearby_screen_t> nearby_screens_t;
4394
4395 15487811 static nearby_screens_t get_nearby_screens_non_scrolling_region()
4396 {
4397 15487811 nearby_screens_t nearby_screens;
4398
4399 15487811 mapscr* base_scr = origin_scr;
4400
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 auto& nearby_screen = nearby_screens.emplace_back();
4401 15487811 nearby_screen.screen = cur_screen;
4402
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 nearby_screen.screen_handles = create_screen_handles(base_scr);
4403
4404 15487811 return nearby_screens;
4405
1/2
✓ Branch 0 taken 15487811 times.
✗ Branch 1 not taken.
15487811 }
4406
4407 48296 static nearby_screens_t get_nearby_screens_scrolling_region()
4408 {
4409 48296 nearby_screens_t nearby_screens;
4410
4411
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x0 = viewport.left() / 256;
4412
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_x1 = (viewport.right() - 1) / 256;
4413
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y0 = viewport.top() / 176;
4414
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 int screens_y1 = (viewport.bottom() - 1) / 176;
4415
4416
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x0 = std::clamp(screens_x0, 0, 15);
4417
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_x1 = std::clamp(screens_x1, 0, 15);
4418
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y0 = std::clamp(screens_y0, 0, 8);
4419
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 screens_y1 = std::clamp(screens_y1, 0, 8);
4420
4421
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 79928 times.
128224 for (int x = screens_x0; x <= screens_x1; x++)
4422 {
4423
2/2
✓ Branch 0 taken 169672 times.
✓ Branch 1 taken 79928 times.
249600 for (int y = screens_y0; y <= screens_y1; y++)
4424 {
4425 169672 int screen = cur_screen + x + y*16;
4426
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!is_in_current_region(screen)) continue;
4427
4428
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 mapscr* base_scr = get_scr(screen);
4429
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 if (!base_scr->is_valid()) continue;
4430
4431
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
4432
4433
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 auto& nearby_screen = nearby_screens.emplace_back();
4434 169672 nearby_screen.screen = screen;
4435 169672 nearby_screen.offx = offx;
4436 169672 nearby_screen.offy = offy;
4437
1/2
✓ Branch 0 taken 169672 times.
✗ Branch 1 not taken.
169672 nearby_screen.screen_handles = create_screen_handles(base_scr);
4438 169672 }
4439 79928 }
4440
4441 48296 return nearby_screens;
4442
1/2
✓ Branch 0 taken 48296 times.
✗ Branch 1 not taken.
48296 }
4443
4444 3658 static nearby_screens_t get_nearby_screens_smooth_maze()
4445 {
4446 3658 nearby_screens_t nearby_screens;
4447
4448
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x0 = viewport.left() / 256;
4449
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_x1 = (viewport.right() - 1) / 256;
4450
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y0 = viewport.top() / 176;
4451
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 int screens_y1 = (viewport.bottom() - 1) / 176;
4452
4453
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.left() < 0) screens_x0--;
4454
2/4
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
3658 if (viewport.top() < 0) screens_y0--;
4455
4456
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 7308 times.
10966 for (int x = screens_x0; x <= screens_x1; x++)
4457 {
4458
2/2
✓ Branch 0 taken 18600 times.
✓ Branch 1 taken 7308 times.
25908 for (int y = screens_y0; y <= screens_y1; y++)
4459 {
4460 18600 int screen = -1;
4461 mapscr* base_scr;
4462 int offx, offy;
4463
4464 18600 mapscr* maze_scr = maze_state.scr;
4465 18600 int maze_screen = maze_scr->screen;
4466
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_x = get_region_relative_dx(maze_screen);
4467
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 int maze_screen_y = get_region_relative_dy(maze_screen);
4468 18600 int maze_screen_dx = x - maze_screen_x;
4469 18600 int maze_screen_dy = y - maze_screen_y;
4470 18600 int exitdir = maze_scr->exitdir;
4471
4472 bool should_draw_maze_screen;
4473
2/2
✓ Branch 0 taken 9052 times.
✓ Branch 1 taken 9548 times.
18600 if (maze_state.lost)
4474 {
4475 9548 should_draw_maze_screen = true;
4476 9548 }
4477 else
4478 {
4479 9052 should_draw_maze_screen = true;
4480
4/6
✓ Branch 0 taken 9052 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6844 times.
✓ Branch 3 taken 2208 times.
✓ Branch 4 taken 6844 times.
✗ Branch 5 not taken.
9052 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != exitdir && XY_DELTA_TO_DIR(0, maze_screen_dy) != exitdir;
4481
2/2
✓ Branch 0 taken 3850 times.
✓ Branch 1 taken 5202 times.
9052 if (maze_state.enter_dir != dir_invalid)
4482
4/6
✓ Branch 0 taken 3850 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3304 times.
✓ Branch 3 taken 546 times.
✓ Branch 4 taken 3304 times.
✗ Branch 5 not taken.
3850 should_draw_maze_screen &= XY_DELTA_TO_DIR(maze_screen_dx, 0) != maze_state.enter_dir && XY_DELTA_TO_DIR(0, maze_screen_dy) != maze_state.enter_dir;
4483 }
4484
4485
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (should_draw_maze_screen)
4486 {
4487 16048 screen = maze_state.scr->screen;
4488 16048 base_scr = maze_state.scr;
4489
1/2
✓ Branch 0 taken 16048 times.
✗ Branch 1 not taken.
16048 std::tie(offx, offy) = translate_screen_coordinates_to_world(cur_screen + x + y*16);
4490 16048 }
4491
4492
2/2
✓ Branch 0 taken 16048 times.
✓ Branch 1 taken 2552 times.
18600 if (screen == -1)
4493 {
4494 2552 screen = cur_screen + x + y*16;
4495
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!is_in_current_region(screen)) continue;
4496
4497
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 base_scr = get_scr(screen);
4498
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 if (!base_scr->is_valid()) continue;
4499
4500
1/2
✓ Branch 0 taken 2552 times.
✗ Branch 1 not taken.
2552 std::tie(offx, offy) = translate_screen_coordinates_to_world(screen);
4501 2552 }
4502
4503
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 auto& nearby_screen = nearby_screens.emplace_back();
4504 18600 nearby_screen.screen = screen;
4505 18600 nearby_screen.offx = offx;
4506 18600 nearby_screen.offy = offy;
4507
1/2
✓ Branch 0 taken 18600 times.
✗ Branch 1 not taken.
18600 nearby_screen.screen_handles = create_screen_handles(base_scr);
4508 18600 }
4509 7308 }
4510
4511 3658 return nearby_screens;
4512
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 }
4513
4514 15539765 static nearby_screens_t get_nearby_screens()
4515 {
4516
4/4
✓ Branch 0 taken 9214 times.
✓ Branch 1 taken 15530551 times.
✓ Branch 2 taken 3658 times.
✓ Branch 3 taken 5556 times.
15539765 if (maze_state.active && maze_state.loopy)
4517 3658 return get_nearby_screens_smooth_maze();
4518
4519
2/2
✓ Branch 0 taken 48296 times.
✓ Branch 1 taken 15487811 times.
15536107 if (is_in_scrolling_region())
4520 48296 return get_nearby_screens_scrolling_region();
4521
4522 15487811 return get_nearby_screens_non_scrolling_region();
4523 15539765 }
4524
4525 202038438 static void for_every_nearby_screen(const nearby_screens_t& nearby_screens, const std::function <void (screen_handles_t, int, int, int)>& fn)
4526 {
4527
2/2
✓ Branch 0 taken 203823040 times.
✓ Branch 1 taken 202038438 times.
405861478 for (auto& nearby_screen : nearby_screens)
4528 203823040 fn(nearby_screen.screen_handles, nearby_screen.screen, nearby_screen.offx, nearby_screen.offy);
4529 202038438 }
4530
4531 124318120 static void draw_msgstr(byte layer, BITMAP* dest = nullptr)
4532 {
4533
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 108778355 times.
124318120 if(layer != msgstr_layer) return;
4534
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!dest) dest = framebuf;
4535
4536
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_bg_display_buf->clip))
4537 {
4538 679438 blit_msgstr_bg(dest,0,0,0,playing_field_offset,256,176);
4539 679438 }
4540
4541
2/2
✓ Branch 0 taken 679438 times.
✓ Branch 1 taken 14860327 times.
15539765 if(!(msg_portrait_display_buf->clip))
4542 {
4543 679438 blit_msgstr_prt(dest,0,0,0,playing_field_offset,256,176);
4544 679438 }
4545
4546
2/2
✓ Branch 0 taken 692845 times.
✓ Branch 1 taken 14846920 times.
15539765 if(!(msg_txt_display_buf->clip))
4547 {
4548 692845 blit_msgstr_fg(dest,0,0,0,playing_field_offset,256,176);
4549 692845 }
4550 124318120 }
4551
4552 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y);
4553
4554 62159060 static void set_draw_screen_clip(BITMAP* bmp)
4555 {
4556 62159060 set_clip_rect(bmp, draw_screen_clip_rect_x1, draw_screen_clip_rect_y1, draw_screen_clip_rect_x2, draw_screen_clip_rect_y2);
4557 62159060 }
4558
4559 46119039 void draw_screen(bool showhero, bool runGeneric)
4560 {
4561 46119039 clear_info_bmp();
4562
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46119039 times.
46119039 if((GameFlags & (GAMEFLAG_SCRIPTMENU_ACTIVE|GAMEFLAG_F6SCRIPT_ACTIVE))!=0)
4563 {
4564 FFCore.doScriptMenuDraws();
4565 return;
4566 }
4567
4568
2/2
✓ Branch 0 taken 31180939 times.
✓ Branch 1 taken 14938100 times.
46119039 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_PRE_DRAW);
4569
4570 46119039 clear_bitmap(framebuf);
4571 46119039 clear_clip_rect(framebuf);
4572
4573 46119039 int32_t cmby2=0;
4574
4575 // Draw some background layers
4576 46119039 clear_bitmap(scrollbuf);
4577
4578 46119039 auto nearby_screens = get_nearby_screens();
4579
4580 // Handle layer 2/3 possibly being background layers.
4581
1/2
✓ Branch 0 taken 46119039 times.
✗ Branch 1 not taken.
61795122 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4582 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4583
2/2
✓ Branch 0 taken 15548802 times.
✓ Branch 1 taken 127281 times.
15676083 if (XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4584 127281 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4585 15676083 });
4586
4587
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 45991758 times.
46119039 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4588 {
4589
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 do_layer_primitives(scrollbuf, 2);
4590
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 particles.draw(scrollbuf, true, 2);
4591 127281 }
4592
2/2
✓ Branch 0 taken 15539765 times.
✓ Branch 1 taken 30579274 times.
46119039 _do_current_ffc_layer(scrollbuf, -2);
4593
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15412484 times.
15539765 if (XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4594
1/2
✓ Branch 0 taken 127281 times.
✗ Branch 1 not taken.
127281 draw_msgstr(2, scrollbuf);
4595
4596
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4597 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4598
2/2
✓ Branch 0 taken 15583424 times.
✓ Branch 1 taken 92659 times.
15676083 if (XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4599 92659 do_layer(scrollbuf, 0, screen_handles[3], offx, offy);
4600 15676083 });
4601
4602
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4603 {
4604
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 do_layer_primitives(scrollbuf, 3);
4605
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 particles.draw(scrollbuf, true, 3);
4606 92659 }
4607
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, -3);
4608
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15447106 times.
15539765 if (XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4609
1/2
✓ Branch 0 taken 92659 times.
✗ Branch 1 not taken.
92659 draw_msgstr(3, scrollbuf);
4610
4611 // Draw the main combo screens ("layer 0").
4612
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4613 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15676083 times.
15676083 if (lenscheck(base_scr, 0))
4615 {
4616 15676083 putscr(base_scr, scrollbuf, offx, offy + playing_field_offset);
4617 15676083 }
4618 15676083 });
4619
4620
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (lenscheck(hero_scr, 0))
4621 {
4622
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if(!get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4623
3/4
✓ Branch 0 taken 466049 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4136 times.
✓ Branch 3 taken 461913 times.
470185 if(mblock2.draw(scrollbuf,0))
4624
1/2
✓ Branch 0 taken 4136 times.
✗ Branch 1 not taken.
4136 do_primitives(scrollbuf, SPLAYER_MOVINGBLOCK);
4625 15539765 }
4626
4627 // Lens hints, then primitives, then particles.
4628
6/10
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 5876 times.
✓ Branch 9 taken 4153 times.
15539765 if((lensclk || (get_debug() && zc_getkey(KEY_L))) && !get_qr(qr_OLDLENSORDER))
4629 {
4630
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 draw_lens_under(scrollbuf, false);
4631
1/2
✓ Branch 0 taken 5876 times.
✗ Branch 1 not taken.
5876 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4632 5876 }
4633
4634
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
15539765 if(show_layers[0] && lenscheck(hero_scr,0))
4635
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, 0);
4636
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 0);
4637
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 0);
4638
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(0, scrollbuf);
4639
4640
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(scrollbuf);
4641
4642
2/2
✓ Branch 0 taken 15196506 times.
✓ Branch 1 taken 343259 times.
15539765 if(!(get_qr(qr_LAYER12UNDERCAVE)))
4643 {
4644
4/4
✓ Branch 0 taken 15194632 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 15106248 times.
30356386 if(showhero &&
4645
4/6
✓ Branch 0 taken 15194632 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15159880 times.
✓ Branch 3 taken 34752 times.
✓ Branch 4 taken 15159880 times.
✗ Branch 5 not taken.
15194632 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4646 {
4647
3/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53632 times.
✓ Branch 3 taken 34752 times.
88384 if(Hero.getAction()==climbcovertop)
4648 {
4649 34752 cmby2=16;
4650 34752 }
4651
2/4
✓ Branch 0 taken 53632 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 53632 times.
53632 else if(Hero.getAction()==climbcoverbottom)
4652 {
4653 53632 cmby2=-16;
4654 53632 }
4655
4656
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw2(scrollbuf,true);
4657
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 Hero.draw(scrollbuf);
4658
1/2
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
88384 decorations.draw(scrollbuf,true);
4659
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccx = (int32_t)Hero.getClimbCoverX();
4660
2/4
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
88384 int32_t ccy = (int32_t)Hero.getClimbCoverY();
4661
4662
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4663
3/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88384 times.
✗ Branch 5 not taken.
88384 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4664
4665
4/6
✓ Branch 0 taken 88384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 88384 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✓ Branch 5 taken 73152 times.
88384 if(int32_t(Hero.getX())&15)
4666 {
4667
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4668
3/6
✓ Branch 0 taken 15232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15232 times.
✗ Branch 5 not taken.
15232 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4669 15232 }
4670 88384 }
4671 15196506 }
4672
4673
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4674 15676083 do_layer(scrollbuf, 0, screen_handles[1], offx, offy); // LAYER 1
4675 15676083 });
4676
4677
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(scrollbuf, 1);
4678
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(scrollbuf, true, 1);
4679
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 1);
4680
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(1, scrollbuf);
4681
4682 // Handle layer 2 NOT being used as background layers.
4683
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4684 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4685
2/2
✓ Branch 0 taken 127281 times.
✓ Branch 1 taken 15548802 times.
15676083 if (!XOR(base_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4686 15548802 do_layer(scrollbuf, 0, screen_handles[2], offx, offy);
4687 15676083 });
4688
4689
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4690 {
4691
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 do_layer_primitives(scrollbuf, 2);
4692
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 particles.draw(scrollbuf, true, 2);
4693 15412484 }
4694
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(scrollbuf, 2);
4695
2/2
✓ Branch 0 taken 15412484 times.
✓ Branch 1 taken 127281 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
4696
1/2
✓ Branch 0 taken 15412484 times.
✗ Branch 1 not taken.
15412484 draw_msgstr(2, scrollbuf);
4697
4698
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(scrollbuf, SPLAYER_FFC_DRAW);
4699
4700
2/2
✓ Branch 0 taken 343259 times.
✓ Branch 1 taken 15196506 times.
15539765 if(get_qr(qr_LAYER12UNDERCAVE))
4701 {
4702
2/4
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 343259 times.
686518 if(showhero &&
4703
3/6
✓ Branch 0 taken 343259 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 343259 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 343259 times.
✗ Branch 5 not taken.
343259 ((Hero.getAction()==climbcovertop)||(Hero.getAction()==climbcoverbottom)))
4704 {
4705 if(Hero.getAction()==climbcovertop)
4706 {
4707 cmby2=16;
4708 }
4709 else if(Hero.getAction()==climbcoverbottom)
4710 {
4711 cmby2=-16;
4712 }
4713
4714 decorations.draw2(scrollbuf,true);
4715 Hero.draw(scrollbuf);
4716 decorations.draw(scrollbuf,true);
4717 int32_t ccx = (int32_t)(Hero.getClimbCoverX());
4718 int32_t ccy = (int32_t)(Hero.getClimbCoverY());
4719
4720 overcombo(scrollbuf,ccx-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy+cmby2),MAPCSET(ccx,ccy+cmby2));
4721 putcombo(scrollbuf,ccx-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx,ccy),MAPCSET(ccx,ccy));
4722
4723 if(int32_t(Hero.getX())&15)
4724 {
4725 overcombo(scrollbuf,ccx+16-viewport.x,ccy+cmby2+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy+cmby2),MAPCSET(ccx+16,ccy+cmby2));
4726 putcombo(scrollbuf,ccx+16-viewport.x,ccy+playing_field_offset-viewport.y,MAPCOMBO(ccx+16,ccy),MAPCSET(ccx+16,ccy));
4727 }
4728 }
4729 343259 }
4730
4731
2/2
✓ Branch 0 taken 466049 times.
✓ Branch 1 taken 15073716 times.
15539765 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4732 {
4733
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
30283750 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4734 15210034 do_layer(scrollbuf, -2, screen_handles[0], offx, offy); // push blocks!
4735
2/2
✓ Branch 0 taken 14478915 times.
✓ Branch 1 taken 731119 times.
15210034 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
4736 {
4737 731119 do_layer(scrollbuf, -2, screen_handles[1], offx, offy); // push blocks!
4738 731119 do_layer(scrollbuf, -2, screen_handles[2], offx, offy); // push blocks!
4739 731119 }
4740 15210034 });
4741
4742
1/2
✓ Branch 0 taken 15073716 times.
✗ Branch 1 not taken.
15073716 do_primitives(scrollbuf, SPLAYER_PUSHBLOCK);
4743 15073716 }
4744
4745 // Show walkflags cheat
4746
2/4
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 15539765 times.
15539765 if (show_walkflags || show_effectflags)
4747 {
4748 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4749 do_walkflags(screen_handles, offx, offy);
4750 do_effectflags(screen_handles[0].base_scr, offx, offy);
4751 });
4752
4753 do_walkflags(0, 0);
4754 }
4755
4756
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 putscrdoors(nearby_screens, scrollbuf, 0, playing_field_offset);
4757
4758 // Lens hints, doors etc.
4759
4/8
✓ Branch 0 taken 15529736 times.
✓ Branch 1 taken 10029 times.
✓ Branch 2 taken 15529736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 15529736 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
15539765 if(lensclk || (get_debug() && zc_getkey(KEY_L)))
4760 {
4761
2/2
✓ Branch 0 taken 4153 times.
✓ Branch 1 taken 5876 times.
10029 if(get_qr(qr_OLDLENSORDER))
4762 {
4763
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 draw_lens_under(scrollbuf, false);
4764
1/2
✓ Branch 0 taken 4153 times.
✗ Branch 1 not taken.
4153 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_1);
4765 4153 }
4766
4767
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 draw_lens_under(scrollbuf, true);
4768
1/2
✓ Branch 0 taken 10029 times.
✗ Branch 1 not taken.
10029 do_primitives(scrollbuf, SPLAYER_LENS_UNDER_2);
4769 10029 }
4770
4771 // Blit those layers onto framebuf
4772
4773
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4774
4775
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 blit(scrollbuf, framebuf, 0, 0, 0, 0, 256, 232);
4776
4777 // After this point, scrollbuf is no longer drawn to - so things like dosubscr have access to a "partially rendered" frame.
4778 // I think only used for COOLSCROLL==0? Seems like a silly feature...
4779
4780 // Draw the subscreen, without clipping
4781
2/2
✓ Branch 0 taken 9251384 times.
✓ Branch 1 taken 6288381 times.
15539765 if(!get_qr(qr_SUBSCREENOVERSPRITES))
4782 {
4783 9251384 bool dotime = false;
4784
4/6
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3412853 times.
✓ Branch 3 taken 5838531 times.
✓ Branch 4 taken 3412853 times.
✗ Branch 5 not taken.
9251384 if (replay_version_check(22)) dotime = game->should_show_time();
4785
1/2
✓ Branch 0 taken 9251384 times.
✗ Branch 1 not taken.
9251384 put_passive_subscr(framebuf, 0, 0, dotime, sspUP);
4786 9251384 }
4787
4788 // Draw some sprites onto framebuf
4789
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
4790
4791
2/2
✓ Branch 0 taken 99496 times.
✓ Branch 1 taken 15440269 times.
15539765 if(!(pricesdisplaybuf->clip))
4792 {
4793
1/2
✓ Branch 0 taken 99496 times.
✗ Branch 1 not taken.
99496 masked_blit(pricesdisplaybuf,framebuf,0,0,0,playing_field_offset,256,176);
4794 99496 }
4795
4796
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4797 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4798
4799
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&&(Hero.getAction()!=climbcoverbottom)))
4800 {
4801
1/2
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
15449507 Hero.draw_under(framebuf);
4802
4803
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 141385 times.
✓ Branch 3 taken 15308122 times.
15449507 if(Hero.isSwimming())
4804 {
4805
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw2(framebuf,true);
4806
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 Hero.draw(framebuf);
4807
1/2
✓ Branch 0 taken 141385 times.
✗ Branch 1 not taken.
141385 decorations.draw(framebuf,true);
4808 141385 }
4809 15449507 }
4810
4811
2/2
✓ Branch 0 taken 26095 times.
✓ Branch 1 taken 15513670 times.
15539765 if(drawguys)
4812 {
4813
4/4
✓ Branch 0 taken 1982674 times.
✓ Branch 1 taken 13530996 times.
✓ Branch 2 taken 991089 times.
✓ Branch 3 taken 991585 times.
15513670 if(get_qr(qr_NOFLICKER) || (frame&1))
4814 {
4815 // Just clips sprites if in a repeating, smooth maze.
4816
2/2
✓ Branch 0 taken 14512871 times.
✓ Branch 1 taken 9214 times.
14522085 bool do_clip = maze_state.active && maze_state.loopy;
4817
4818
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4819 {
4820
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✓ Branch 3 taken 8907199 times.
9105142 if(((weapon *)Ewpns.spr(i))->behind)
4821
2/4
✓ Branch 0 taken 197943 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 197943 times.
✗ Branch 3 not taken.
197943 Ewpns.spr(i)->draw(framebuf);
4822 9105142 }
4823
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4824
4825
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4826 {
4827
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✓ Branch 3 taken 4671891 times.
4675096 if(((weapon *)Lwpns.spr(i))->behind)
4828
2/4
✓ Branch 0 taken 3205 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3205 times.
✗ Branch 3 not taken.
3205 Lwpns.spr(i)->draw(framebuf);
4829 4675096 }
4830
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4831
4832
6/6
✓ Branch 0 taken 9785221 times.
✓ Branch 1 taken 4736864 times.
✓ Branch 2 taken 1348300 times.
✓ Branch 3 taken 8436921 times.
✓ Branch 4 taken 674011 times.
✓ Branch 5 taken 674289 times.
14522085 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4833 {
4834
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 9107274 times.
9110932 if (do_clip)
4835
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.drawshadow_smooth_maze(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4836 else
4837
1/2
✓ Branch 0 taken 9107274 times.
✗ Branch 1 not taken.
9107274 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4838 9110932 }
4839
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4840
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 guys.draw_smooth_maze(framebuf);
4841 else
4842
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 guys.draw(framebuf,true);
4843
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4844 {
4845 3658 int maze_screen = maze_state.scr->screen;
4846
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4847
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4848 3658 }
4849
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4850
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4851
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4852
4853
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 chainlinks.draw(framebuf,true);
4854
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4855 //Lwpns.draw(framebuf,true);
4856
4857
3/4
✓ Branch 0 taken 23627227 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9105142 times.
✓ Branch 3 taken 14522085 times.
23627227 for(int32_t i=0; i<Ewpns.Count(); i++)
4858 {
4859
3/4
✓ Branch 0 taken 9105142 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✓ Branch 3 taken 197943 times.
9105142 if(!((weapon *)Ewpns.spr(i))->behind)
4860
2/4
✓ Branch 0 taken 8907199 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8907199 times.
✗ Branch 3 not taken.
8907199 Ewpns.spr(i)->draw(framebuf);
4861 9105142 }
4862
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4863
4864
3/4
✓ Branch 0 taken 19197181 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4675096 times.
✓ Branch 3 taken 14522085 times.
19197181 for(int32_t i=0; i<Lwpns.Count(); i++)
4865 {
4866
3/4
✓ Branch 0 taken 4675096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✓ Branch 3 taken 3205 times.
4675096 if(!((weapon *)Lwpns.spr(i))->behind)
4867
2/4
✓ Branch 0 taken 4671891 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4671891 times.
✗ Branch 3 not taken.
4671891 Lwpns.spr(i)->draw(framebuf);
4868 4675096 }
4869
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4870
4871
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4872
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 items.draw_smooth_maze(framebuf);
4873 else
4874
1/2
✓ Branch 0 taken 14518427 times.
✗ Branch 1 not taken.
14518427 items.draw(framebuf,true);
4875
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4876 {
4877 3658 int maze_screen = maze_state.scr->screen;
4878
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 auto [sx, sy] = translate_screen_coordinates_to_world(maze_screen);
4879
5/10
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3658 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3658 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 3658 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 3658 times.
✗ Branch 9 not taken.
18290 set_clip_rect(framebuf, sx - viewport.x, sy - viewport.y, sx + 256 - viewport.x, sy + 176 - viewport.y);
4880 3658 }
4881
1/2
✓ Branch 0 taken 14522085 times.
✗ Branch 1 not taken.
14522085 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4882
2/2
✓ Branch 0 taken 3658 times.
✓ Branch 1 taken 14518427 times.
14522085 if (do_clip)
4883
1/2
✓ Branch 0 taken 3658 times.
✗ Branch 1 not taken.
3658 clear_clip_rect(framebuf);
4884 14522085 }
4885 else
4886 {
4887
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4888 {
4889
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✓ Branch 3 taken 496727 times.
505372 if(((weapon *)Ewpns.spr(i))->behind)
4890
2/4
✓ Branch 0 taken 8645 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8645 times.
✗ Branch 3 not taken.
8645 Ewpns.spr(i)->draw(framebuf);
4891 505372 }
4892
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_BEHIND_DRAW);
4893
4894
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4895 {
4896
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 231146 times.
231146 if(((weapon *)Lwpns.spr(i))->behind)
4897 Lwpns.spr(i)->draw(framebuf);
4898 231146 }
4899
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_BEHIND_DRAW);
4900
4901
3/4
✓ Branch 0 taken 228620 times.
✓ Branch 1 taken 762965 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 228620 times.
991585 if(get_qr(qr_SHADOWS)&&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4902 {
4903
1/2
✓ Branch 0 taken 228620 times.
✗ Branch 1 not taken.
228620 guys.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0,true);
4904 228620 }
4905
4906
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 items.draw(framebuf,false);
4907
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_ITEMSPRITE_DRAW);
4908
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 chainlinks.draw(framebuf,false);
4909
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
4910 //Lwpns.draw(framebuf,false);
4911
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 guys.draw(framebuf,false);
4912
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_NPC_DRAW);
4913
4914
3/4
✓ Branch 0 taken 1496957 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 505372 times.
✓ Branch 3 taken 991585 times.
1496957 for(int32_t i=0; i<Ewpns.Count(); i++)
4915 {
4916
3/4
✓ Branch 0 taken 505372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✓ Branch 3 taken 8645 times.
505372 if(!((weapon *)Ewpns.spr(i))->behind)
4917 {
4918
2/4
✓ Branch 0 taken 496727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 496727 times.
✗ Branch 3 not taken.
496727 Ewpns.spr(i)->draw(framebuf);
4919 496727 }
4920 505372 }
4921
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_EWEAP_FRONT_DRAW);
4922
4923
3/4
✓ Branch 0 taken 1222731 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✓ Branch 3 taken 991585 times.
1222731 for(int32_t i=0; i<Lwpns.Count(); i++)
4924 {
4925
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 if(!((weapon *)Lwpns.spr(i))->behind)
4926 {
4927
2/4
✓ Branch 0 taken 231146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 231146 times.
✗ Branch 3 not taken.
231146 Lwpns.spr(i)->draw(framebuf);
4928 231146 }
4929 231146 }
4930
1/2
✓ Branch 0 taken 991585 times.
✗ Branch 1 not taken.
991585 do_primitives(framebuf, SPLAYER_LWEAP_FRONT_DRAW);
4931 }
4932
4933
1/2
✓ Branch 0 taken 15513670 times.
✗ Branch 1 not taken.
15513670 guys.draw2(framebuf,true);
4934 15513670 }
4935
4936
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(mirror_portal.destdmap > -1)
4937 mirror_portal.draw(framebuf);
4938
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 portals.draw(framebuf,true);
4939
4940
8/10
✓ Branch 0 taken 15537891 times.
✓ Branch 1 taken 1874 times.
✓ Branch 2 taken 15537891 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15503139 times.
✓ Branch 5 taken 34752 times.
✓ Branch 6 taken 15503139 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15449507 times.
✓ Branch 9 taken 53632 times.
15539765 if(showhero && ((Hero.getAction()!=climbcovertop)&& (Hero.getAction()!=climbcoverbottom)))
4941 {
4942
2/2
✓ Branch 0 taken 14989874 times.
✓ Branch 1 taken 459633 times.
15449507 if(get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
4943 {
4944
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 mblock2.draw(framebuf,-1);
4945
1/2
✓ Branch 0 taken 14989874 times.
✗ Branch 1 not taken.
14989874 do_primitives(framebuf, SPLAYER_MOVINGBLOCK);
4946 14989874 }
4947
3/4
✓ Branch 0 taken 15449507 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✓ Branch 3 taken 141385 times.
15449507 if(!Hero.isSwimming())
4948 {
4949
8/12
✓ Branch 0 taken 15308122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15288952 times.
✓ Branch 5 taken 19170 times.
✓ Branch 6 taken 15288952 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 15288952 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 1370 times.
✓ Branch 11 taken 15306752 times.
15308122 if((Hero.getZ()>0 || Hero.getFakeZ()>0) &&(!get_qr(qr_SHADOWSFLICKER)||frame&1))
4950 {
4951
2/2
✓ Branch 0 taken 18485 times.
✓ Branch 1 taken 15289637 times.
15308122 Hero.drawshadow(framebuf,get_qr(qr_TRANSSHADOWS)!=0);
4952 18485 }
4953
4954
6/8
✓ Branch 0 taken 15308122 times.
✓ Branch 1 taken 15289637 times.
✓ Branch 2 taken 15308122 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15308122 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 15294058 times.
✓ Branch 7 taken 14064 times.
18485 if(Hero.getZ() <= (zfix)zinit.jump_hero_layer_threshold)
4955 {
4956
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw2(framebuf,true);
4957
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 Hero.draw(framebuf);
4958
1/2
✓ Branch 0 taken 15294058 times.
✗ Branch 1 not taken.
15294058 decorations.draw(framebuf,true);
4959 15294058 }
4960 15308122 }
4961 15449507 }
4962
4963
3/4
✓ Branch 0 taken 54880218 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✓ Branch 3 taken 15539765 times.
54880218 for(int32_t i=0; i<guys.Count(); i++)
4964 {
4965
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15945464 times.
✓ Branch 3 taken 23394989 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALK)
4966 {
4967
3/4
✓ Branch 0 taken 15945464 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✓ Branch 3 taken 15938169 times.
15945464 if(((eStalfos*)guys.spr(i))->hashero)
4968 {
4969
2/4
✓ Branch 0 taken 7295 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7295 times.
✗ Branch 3 not taken.
7295 guys.spr(i)->draw(framebuf);
4970 7295 }
4971 15945464 }
4972
4973
3/4
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 507162 times.
✓ Branch 3 taken 38833291 times.
39340453 if(((enemy*)guys.spr(i))->type == eeWALLM)
4974 {
4975
3/4
✓ Branch 0 taken 507162 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✓ Branch 3 taken 505833 times.
507162 if(((eWallM*)guys.spr(i))->hashero)
4976 {
4977
2/4
✓ Branch 0 taken 1329 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1329 times.
✗ Branch 3 not taken.
1329 guys.spr(i)->draw(framebuf);
4978 1329 }
4979 507162 }
4980
4981
11/20
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39340453 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39340453 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 39340453 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 39340453 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 39340453 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 39340453 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 39340453 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 39340453 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 1342694 times.
✓ Branch 19 taken 37997759 times.
39340453 if(guys.spr(i)->z+guys.spr(i)->fakez > Hero.getZ()+Hero.getFakeZ())
4982 {
4983 //Jumping enemies in front of Hero.
4984
2/4
✓ Branch 0 taken 1342694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1342694 times.
✗ Branch 3 not taken.
1342694 guys.spr(i)->draw(framebuf);
4985 1342694 }
4986
1/2
✓ Branch 0 taken 39340453 times.
✗ Branch 1 not taken.
39340453 do_primitives(framebuf, SPLAYER_NPC_ABOVEPLAYER_DRAW);
4987 39340453 }
4988
4989 // Draw some layers onto framebuf
4990
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
4991
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
4992 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
4993
4994 // Handle layer 3 NOT being used as background layers.
4995
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
4996 15676083 mapscr* base_scr = screen_handles[0].base_scr;
4997
2/2
✓ Branch 0 taken 92659 times.
✓ Branch 1 taken 15583424 times.
15676083 if (!XOR(base_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
4998 15583424 do_layer(framebuf, 0, screen_handles[3], offx, offy);
4999 15676083 });
5000
5001
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5002 {
5003
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 do_layer_primitives(framebuf, 3);
5004
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 particles.draw(framebuf, true, 3);
5005 15447106 }
5006
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 3);
5007
2/2
✓ Branch 0 taken 15447106 times.
✓ Branch 1 taken 92659 times.
15539765 if(!XOR(origin_scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
5008
1/2
✓ Branch 0 taken 15447106 times.
✗ Branch 1 not taken.
15447106 draw_msgstr(3);
5009
5010
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5011 15676083 do_layer(framebuf, 0, screen_handles[4], offx, offy);
5012 15676083 });
5013
5014
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 4);
5015
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 4);
5016
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 4);
5017
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(4);
5018
5019
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5020 15676083 do_layer(framebuf, -1, screen_handles[0], offx, offy);
5021
2/2
✓ Branch 0 taken 14400195 times.
✓ Branch 1 taken 1275888 times.
15676083 if (get_qr(qr_OVERHEAD_COMBOS_L1_L2))
5022 {
5023 1275888 do_layer(framebuf, -1, screen_handles[1], offx, offy);
5024 1275888 do_layer(framebuf, -1, screen_handles[2], offx, offy);
5025 1275888 }
5026 15676083 });
5027
5028
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_CMB);
5029
5030 // Draw some flying sprites onto framebuf
5031
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 clear_clip_rect(framebuf);
5032
5/6
✓ Branch 0 taken 15494139 times.
✓ Branch 1 taken 45626 times.
✓ Branch 2 taken 6328 times.
✓ Branch 3 taken 15487811 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 6328 times.
15539765 if (!is_extended_height_mode() && is_in_scrolling_region() && !get_qr(qr_SUBSCREENOVERSPRITES))
5033 add_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5034
5035 //Jumping Hero and jumping enemies are drawn on this layer.
5036
5/8
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15539765 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15539765 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 14064 times.
✓ Branch 7 taken 15525701 times.
15539765 if(Hero.getZ() > (zfix)zinit.jump_hero_layer_threshold)
5037 {
5038
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw2(framebuf,false);
5039
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 Hero.draw(framebuf);
5040
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 chainlinks.draw(framebuf,true);
5041
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_CHAINLINK_DRAW);
5042
5043
3/4
✓ Branch 0 taken 16806 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✓ Branch 3 taken 14064 times.
16806 for(int32_t i=0; i<Lwpns.Count(); i++)
5044 {
5045
9/16
✓ Branch 0 taken 2742 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2742 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2742 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2742 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2742 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2742 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2742 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 239 times.
✓ Branch 15 taken 2503 times.
2742 if(Lwpns.spr(i)->z+Lwpns.spr(i)->fakez > (zfix)zinit.jump_hero_layer_threshold)
5046 {
5047
2/4
✓ Branch 0 taken 239 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 239 times.
✗ Branch 3 not taken.
239 Lwpns.spr(i)->draw(framebuf);
5048 239 }
5049 2742 }
5050
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 do_primitives(framebuf, SPLAYER_LWEAP_ABOVE_DRAW);
5051
5052
1/2
✓ Branch 0 taken 14064 times.
✗ Branch 1 not taken.
14064 decorations.draw(framebuf,false);
5053 14064 }
5054
5055
5/6
✓ Branch 0 taken 3288981 times.
✓ Branch 1 taken 12250784 times.
✓ Branch 2 taken 44334375 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 32083591 times.
✓ Branch 5 taken 12250784 times.
47623356 if(!get_qr(qr_ENEMIESZAXIS)) for(int32_t i=0; i<guys.Count(); i++)
5056 {
5057
13/22
✓ Branch 0 taken 32083591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 32083591 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27177493 times.
✓ Branch 5 taken 4906098 times.
✓ Branch 6 taken 27177493 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 27177493 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 27177493 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 27177493 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 27177493 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 27177493 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 27177493 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 6568 times.
✓ Branch 21 taken 27170925 times.
32083591 if((isflier(guys.spr(i)->id)) || (guys.spr(i)->z+guys.spr(i)->fakez) > (zfix)zinit.jump_hero_layer_threshold)
5058 {
5059
2/4
✓ Branch 0 taken 4912666 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4912666 times.
✗ Branch 3 not taken.
4912666 guys.spr(i)->draw(framebuf);
5060 4912666 }
5061 44334375 }
5062 else
5063 {
5064
3/4
✓ Branch 0 taken 10545843 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✓ Branch 3 taken 3288981 times.
10545843 for(int32_t i=0; i<guys.Count(); i++)
5065 {
5066
13/22
✓ Branch 0 taken 7256862 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7256862 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6081157 times.
✓ Branch 5 taken 1175705 times.
✓ Branch 6 taken 6081157 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6081157 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6081157 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 5594346 times.
✓ Branch 13 taken 486811 times.
✓ Branch 14 taken 5594346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 5594346 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 5594346 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 5594346 times.
7256862 if((isflier(guys.spr(i)->id)) || guys.spr(i)->z > 0 || guys.spr(i)->fakez > 0)
5067 {
5068
2/4
✓ Branch 0 taken 1662516 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1662516 times.
✗ Branch 3 not taken.
1662516 guys.spr(i)->draw(framebuf);
5069 1662516 }
5070 7256862 }
5071 }
5072
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_NPC_AIRBORNE_DRAW);
5073
5074 // Draw the Moving Fairy above layer 3
5075
3/4
✓ Branch 0 taken 18684859 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3145094 times.
✓ Branch 3 taken 15539765 times.
18684859 for(int32_t i=0; i<items.Count(); i++)
5076
6/8
✓ Branch 0 taken 3145094 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69867 times.
✓ Branch 3 taken 3075227 times.
✓ Branch 4 taken 69867 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 60153 times.
✓ Branch 7 taken 9714 times.
3205247 if(itemsbuf[items.spr(i)->id].type == itype_fairy && itemsbuf[items.spr(i)->id].misc3)
5077
2/4
✓ Branch 0 taken 60153 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 60153 times.
✗ Branch 3 not taken.
60153 items.spr(i)->draw(framebuf);
5078
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_FAIRYITEM_DRAW);
5079
5080 // Draw some layers onto framebuf
5081
5082
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_draw_screen_clip(framebuf);
5083
5084
2/2
✓ Branch 0 taken 15525413 times.
✓ Branch 1 taken 14352 times.
15539765 if (lightbeam_present)
5085 {
5086 14352 color_map = &trans_table2;
5087
2/2
✓ Branch 0 taken 13114 times.
✓ Branch 1 taken 1238 times.
14352 if(get_qr(qr_LIGHTBEAM_TRANSPARENT))
5088
1/2
✓ Branch 0 taken 13114 times.
✗ Branch 1 not taken.
13114 draw_trans_sprite(framebuf, lightbeam_bmp, 0, playing_field_offset);
5089 else
5090
1/2
✓ Branch 0 taken 1238 times.
✗ Branch 1 not taken.
1238 masked_blit(lightbeam_bmp, framebuf, 0, 0, 0, playing_field_offset, 256, 176);
5091 14352 color_map = &trans_table;
5092 14352 }
5093
5094
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5095 15676083 do_layer(framebuf, 0, screen_handles[5], offx, offy);
5096 15676083 });
5097
5098
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 5);
5099
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 5);
5100
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 5);
5101
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(5);
5102
5103
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, -1); // 'overhead' freeform combos
5104
5105
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_primitives(framebuf, SPLAYER_OVERHEAD_FFC);
5106
5107
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5108 15676083 do_layer(framebuf, 0, screen_handles[6], offx, offy);
5109 15676083 });
5110
5111
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 do_layer_primitives(framebuf, 6);
5112
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 particles.draw(framebuf, true, 6);
5113
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 6);
5114
5115 15539765 bool any_dark = false;
5116
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5117 15676083 mapscr* base_scr = screen_handles[0].scr;
5118 15676083 any_dark |= is_dark(base_scr);
5119 15676083 });
5120
5121 // Handle low drawn darkness
5122
4/4
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 1025781 times.
✓ Branch 3 taken 243771 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && any_dark)
5123 {
5124
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5125 250005 mapscr* base_scr = screen_handles[0].scr;
5126 250005 calc_darkroom_combos(base_scr, offx, offy + playing_field_offset);
5127 250005 calc_darkroom_ffcs(base_scr, 0, playing_field_offset);
5128 250005 });
5129
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 if(showhero)
5130
1/2
✓ Branch 0 taken 243771 times.
✗ Branch 1 not taken.
243771 Hero.calc_darkroom_hero(0, -playing_field_offset);
5131
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 243771 times.
493776 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
5132 250005 mapscr* base_scr = screen_handles[0].scr;
5133
2/2
✓ Branch 0 taken 245275 times.
✓ Branch 1 taken 4730 times.
250005 if (!is_dark(base_scr))
5134 {
5135 4730 offy += playing_field_offset;
5136 4730 rectfill(darkscr_bmp, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5137 4730 rectfill(darkscr_bmp_trans, offx - viewport.x, offy - viewport.y, offx - viewport.x + 256 - 1, offy - viewport.y + 176 - 1, 0);
5138 4730 }
5139 250005 });
5140 243771 }
5141
5142 //Darkroom if under the subscreen
5143
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 823284 times.
✓ Branch 3 taken 446268 times.
✓ Branch 4 taken 231780 times.
✓ Branch 5 taken 591504 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && get_qr(qr_NEWDARK_L6) && any_dark)
5144 {
5145
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5146
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5147
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 231780 times.
231780 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5148 {
5149 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5150 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5151 }
5152
5153 231780 color_map = &trans_table2;
5154
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 231636 times.
231780 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5155 {
5156
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5157
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5158
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5159 144 }
5160 else
5161 {
5162
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5163
1/2
✓ Branch 0 taken 231636 times.
✗ Branch 1 not taken.
231636 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5164 }
5165 231780 color_map = &trans_table;
5166
5167
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5168
1/2
✓ Branch 0 taken 231780 times.
✗ Branch 1 not taken.
231780 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5169 231780 }
5170
5171
3/6
✓ Branch 0 taken 45626 times.
✓ Branch 1 taken 15494139 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45626 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
15539765 if (is_extended_height_mode() && lensclk && !FFCore.system_suspend[susptLENS])
5172 {
5173 draw_lens_over();
5174 --lensclk;
5175 }
5176
5177 // Draw some text on framebuf
5178
5179
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(framebuf,0,0,256,232);
5180
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 if(!get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5181
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(6);
5182
5183 // Draw the subscreen, without clipping
5184
2/2
✓ Branch 0 taken 6288381 times.
✓ Branch 1 taken 9251384 times.
15539765 if(get_qr(qr_SUBSCREENOVERSPRITES))
5185 {
5186
2/4
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6288381 times.
✗ Branch 3 not taken.
6288381 put_passive_subscr(framebuf, 0, 0, game->should_show_time(), sspUP);
5187
5188 // Draw primitives over subscren
5189
1/2
✓ Branch 0 taken 6288381 times.
✗ Branch 1 not taken.
6288381 do_primitives(framebuf, 7); //Layer '7' appears above subscreen if quest rule is set
5190 6288381 }
5191
5192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if(get_qr(qr_LAYER6_STRINGS_OVER_SUBSCREEN))
5193 draw_msgstr(6);
5194
5195 // Handle high-drawn darkness
5196
6/6
✓ Branch 0 taken 1269552 times.
✓ Branch 1 taken 14270213 times.
✓ Branch 2 taken 446268 times.
✓ Branch 3 taken 823284 times.
✓ Branch 4 taken 11991 times.
✓ Branch 5 taken 434277 times.
15539765 if(get_qr(qr_NEW_DARKROOM) && !get_qr(qr_NEWDARK_L6) && any_dark)
5197 {
5198
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_UNDER);
5199
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, playing_field_offset, framebuf->w, framebuf->h);
5200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_DITHER) //dither the entire bitmap
5201 {
5202 ditherblit(darkscr_bmp,darkscr_bmp,0,game->get_dither_type(),game->get_dither_arg());
5203 ditherblit(darkscr_bmp_trans,darkscr_bmp_trans,0,game->get_dither_type(),game->get_dither_arg());
5204 }
5205
5206 11991 color_map = &trans_table2;
5207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11991 times.
11991 if(hero_scr->flags9 & fDARK_TRANS) //draw the dark as transparent
5208 {
5209 draw_trans_sprite(framebuf, darkscr_bmp, 0, 0);
5210 if(get_qr(qr_NEWDARK_TRANS_STACKING))
5211 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5212 }
5213 else
5214 {
5215
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 masked_blit(darkscr_bmp, framebuf, 0, 0, 0, 0, framebuf->w, framebuf->h);
5216
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 draw_trans_sprite(framebuf, darkscr_bmp_trans, 0, 0);
5217 }
5218 11991 color_map = &trans_table;
5219
5220
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 set_clip_rect(framebuf, 0, 0, framebuf->w, framebuf->h);
5221
1/2
✓ Branch 0 taken 11991 times.
✗ Branch 1 not taken.
11991 do_primitives(framebuf, SPLAYER_DARKROOM_OVER);
5222 11991 }
5223
5224
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 _do_current_ffc_layer(framebuf, 7);
5225
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 draw_msgstr(7);
5226
5227
1/2
✓ Branch 0 taken 15539765 times.
✗ Branch 1 not taken.
15539765 set_clip_rect(scrollbuf, 0, 0, scrollbuf->w, scrollbuf->h);
5228
3/4
✓ Branch 0 taken 14938100 times.
✓ Branch 1 taken 601665 times.
✓ Branch 2 taken 14938100 times.
✗ Branch 3 not taken.
15539765 if(runGeneric) FFCore.runGenericPassiveEngine(SCR_TIMING_POST_DRAW);
5229 76698313 }
5230
5231 // TODO: separate setting door data and drawing door
5232 28153 void put_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t type, bool redraw, bool even_walls)
5233 {
5234
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28153 times.
28153 if (type > 8) return;
5235
5236 28153 int32_t d=scr->door_combo_set;
5237
5238
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 15611 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 12542 times.
28153 switch(type)
5239 {
5240 case dt_wall:
5241 case dt_walk:
5242 if(!even_walls)
5243 break;
5244 [[fallthrough]];
5245 case dt_pass:
5246
3/4
✓ Branch 0 taken 1036 times.
✓ Branch 1 taken 11506 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1036 times.
12542 if(!get_qr(qr_REPLACEOPENDOORS) && !even_walls)
5247 1036 break;
5248 [[fallthrough]];
5249 case dt_lock:
5250 case dt_shut:
5251 case dt_boss:
5252 case dt_olck:
5253 case dt_osht:
5254 case dt_obos:
5255 case dt_bomb:
5256
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 7259 times.
✓ Branch 2 taken 6784 times.
✓ Branch 3 taken 6362 times.
✓ Branch 4 taken 6712 times.
27117 switch(side)
5257 {
5258 case up:
5259 7259 scr->data[pos] = DoorComboSets[d].doorcombo_u[type][0];
5260 7259 scr->cset[pos] = DoorComboSets[d].doorcset_u[type][0];
5261 7259 scr->sflag[pos] = 0;
5262 7259 scr->data[pos+1] = DoorComboSets[d].doorcombo_u[type][1];
5263 7259 scr->cset[pos+1] = DoorComboSets[d].doorcset_u[type][1];
5264 7259 scr->sflag[pos+1] = 0;
5265 7259 scr->data[pos+16] = DoorComboSets[d].doorcombo_u[type][2];
5266 7259 scr->cset[pos+16] = DoorComboSets[d].doorcset_u[type][2];
5267 7259 scr->sflag[pos+16] = 0;
5268 7259 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_u[type][3];
5269 7259 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_u[type][3];
5270 7259 scr->sflag[pos+16+1] = 0;
5271
5272
2/2
✓ Branch 0 taken 5435 times.
✓ Branch 1 taken 1824 times.
7259 if(redraw)
5273 {
5274 3648 putcombo(dest,(pos&15)<<4,pos&0xF0,
5275 1824 DoorComboSets[d].doorcombo_u[type][0],
5276 1824 DoorComboSets[d].doorcset_u[type][0]);
5277 3648 putcombo(dest,((pos&15)<<4)+16,pos&0xF0,
5278 1824 DoorComboSets[d].doorcombo_u[type][1],
5279 1824 DoorComboSets[d].doorcset_u[type][1]);
5280 1824 }
5281
5282 7259 break;
5283
5284 case down:
5285 6784 scr->data[pos] = DoorComboSets[d].doorcombo_d[type][0];
5286 6784 scr->cset[pos] = DoorComboSets[d].doorcset_d[type][0];
5287 6784 scr->sflag[pos] = 0;
5288 6784 scr->data[pos+1] = DoorComboSets[d].doorcombo_d[type][1];
5289 6784 scr->cset[pos+1] = DoorComboSets[d].doorcset_d[type][1];
5290 6784 scr->sflag[pos+1] = 0;
5291 6784 scr->data[pos+16] = DoorComboSets[d].doorcombo_d[type][2];
5292 6784 scr->cset[pos+16] = DoorComboSets[d].doorcset_d[type][2];
5293 6784 scr->sflag[pos+16] = 0;
5294 6784 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_d[type][3];
5295 6784 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_d[type][3];
5296 6784 scr->sflag[pos+16+1] = 0;
5297
5298
2/2
✓ Branch 0 taken 5463 times.
✓ Branch 1 taken 1321 times.
6784 if(redraw)
5299 {
5300 2642 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5301 1321 DoorComboSets[d].doorcombo_d[type][2],
5302 1321 DoorComboSets[d].doorcset_d[type][2]);
5303 2642 putcombo(dest,((pos&15)<<4)+16,(pos&0xF0)+16,
5304 1321 DoorComboSets[d].doorcombo_d[type][3],
5305 1321 DoorComboSets[d].doorcset_d[type][3]);
5306 1321 }
5307
5308 6784 break;
5309
5310 case left:
5311 6362 scr->data[pos] = DoorComboSets[d].doorcombo_l[type][0];
5312 6362 scr->cset[pos] = DoorComboSets[d].doorcset_l[type][0];
5313 6362 scr->sflag[pos] = 0;
5314 6362 scr->data[pos+1] = DoorComboSets[d].doorcombo_l[type][1];
5315 6362 scr->cset[pos+1] = DoorComboSets[d].doorcset_l[type][1];
5316 6362 scr->sflag[pos+1] = 0;
5317 6362 scr->data[pos+16] = DoorComboSets[d].doorcombo_l[type][2];
5318 6362 scr->cset[pos+16] = DoorComboSets[d].doorcset_l[type][2];
5319 6362 scr->sflag[pos+16] = 0;
5320 6362 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_l[type][3];
5321 6362 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_l[type][3];
5322 6362 scr->sflag[pos+16+1] = 0;
5323 6362 scr->data[pos+32] = DoorComboSets[d].doorcombo_l[type][4];
5324 6362 scr->cset[pos+32] = DoorComboSets[d].doorcset_l[type][4];
5325 6362 scr->sflag[pos+32] = 0;
5326 6362 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_l[type][5];
5327 6362 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_l[type][5];
5328 6362 scr->sflag[pos+32+1] = 0;
5329
5330
2/2
✓ Branch 0 taken 4873 times.
✓ Branch 1 taken 1489 times.
6362 if(redraw)
5331 {
5332 2978 putcombo(dest,(pos&15)<<4,pos&0xF0,
5333 1489 DoorComboSets[d].doorcombo_l[type][0],
5334 1489 DoorComboSets[d].doorcset_l[type][0]);
5335 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5336 1489 DoorComboSets[d].doorcombo_l[type][2],
5337 1489 DoorComboSets[d].doorcset_l[type][2]);
5338 2978 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5339 1489 DoorComboSets[d].doorcombo_l[type][4],
5340 1489 DoorComboSets[d].doorcset_l[type][4]);
5341 1489 }
5342
5343 6362 break;
5344
5345 case right:
5346 6712 scr->data[pos] = DoorComboSets[d].doorcombo_r[type][0];
5347 6712 scr->cset[pos] = DoorComboSets[d].doorcset_r[type][0];
5348 6712 scr->sflag[pos] = 0;
5349 6712 scr->data[pos+1] = DoorComboSets[d].doorcombo_r[type][1];
5350 6712 scr->cset[pos+1] = DoorComboSets[d].doorcset_r[type][1];
5351 6712 scr->sflag[pos+1] = 0;
5352 6712 scr->data[pos+16] = DoorComboSets[d].doorcombo_r[type][2];
5353 6712 scr->cset[pos+16] = DoorComboSets[d].doorcset_r[type][2];
5354 6712 scr->sflag[pos+16] = 0;
5355 6712 scr->data[pos+16+1] = DoorComboSets[d].doorcombo_r[type][3];
5356 6712 scr->cset[pos+16+1] = DoorComboSets[d].doorcset_r[type][3];
5357 6712 scr->sflag[pos+16+1] = 0;
5358 6712 scr->data[pos+32] = DoorComboSets[d].doorcombo_r[type][4];
5359 6712 scr->cset[pos+32] = DoorComboSets[d].doorcset_r[type][4];
5360 6712 scr->sflag[pos+32] = 0;
5361 6712 scr->data[pos+32+1] = DoorComboSets[d].doorcombo_r[type][5];
5362 6712 scr->cset[pos+32+1] = DoorComboSets[d].doorcset_r[type][5];
5363 6712 scr->sflag[pos+32+1] = 0;
5364
5365
2/2
✓ Branch 0 taken 5058 times.
✓ Branch 1 taken 1654 times.
6712 if(redraw)
5366 {
5367 3308 putcombo(dest,(pos&15)<<4,pos&0xF0,
5368 1654 DoorComboSets[d].doorcombo_r[type][0],
5369 1654 DoorComboSets[d].doorcset_r[type][0]);
5370 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+16,
5371 1654 DoorComboSets[d].doorcombo_r[type][2],
5372 1654 DoorComboSets[d].doorcset_r[type][2]);
5373 3308 putcombo(dest,(pos&15)<<4,(pos&0xF0)+32,
5374 1654 DoorComboSets[d].doorcombo_r[type][4],
5375 1654 DoorComboSets[d].doorcset_r[type][4]);
5376 1654 }
5377
5378 6712 break;
5379 }
5380
5381 27117 break;
5382
5383 default:
5384 break;
5385 }
5386 28153 }
5387
5388 706556 static void over_door(mapscr* scr, BITMAP *dest, int32_t pos, int32_t side, int32_t offx, int32_t offy)
5389 {
5390 706556 int32_t door_combo_set = scr->door_combo_set;
5391 706556 int32_t x = (pos&15)<<4;
5392 706556 int32_t y = (pos&0xF0);
5393 706556 int32_t d = door_combo_set;
5394 706556 x += offx;
5395 706556 y += offy;
5396
5397
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 161136 times.
✓ Branch 2 taken 179643 times.
✓ Branch 3 taken 196353 times.
✓ Branch 4 taken 169424 times.
706556 switch(side)
5398 {
5399 case up:
5400 322272 overcombo2(dest,x,y,
5401 161136 DoorComboSets[d].bombdoorcombo_u[0],
5402 161136 DoorComboSets[d].bombdoorcset_u[0]);
5403 322272 overcombo2(dest,x+16,y,
5404 161136 DoorComboSets[d].bombdoorcombo_u[1],
5405 161136 DoorComboSets[d].bombdoorcset_u[1]);
5406 161136 break;
5407
5408 case down:
5409 359286 overcombo2(dest,x,y,
5410 179643 DoorComboSets[d].bombdoorcombo_d[0],
5411 179643 DoorComboSets[d].bombdoorcset_d[0]);
5412 359286 overcombo2(dest,x+16,y,
5413 179643 DoorComboSets[d].bombdoorcombo_d[1],
5414 179643 DoorComboSets[d].bombdoorcset_d[1]);
5415 179643 break;
5416
5417 case left:
5418 392706 overcombo2(dest,x,y,
5419 196353 DoorComboSets[d].bombdoorcombo_l[0],
5420 196353 DoorComboSets[d].bombdoorcset_l[0]);
5421 392706 overcombo2(dest,x,y+16,
5422 196353 DoorComboSets[d].bombdoorcombo_l[1],
5423 196353 DoorComboSets[d].bombdoorcset_l[1]);
5424 392706 overcombo2(dest,x,y+16,
5425 196353 DoorComboSets[d].bombdoorcombo_l[2],
5426 196353 DoorComboSets[d].bombdoorcset_l[2]);
5427 196353 break;
5428
5429 case right:
5430 338848 overcombo2(dest,x,y,
5431 169424 DoorComboSets[d].bombdoorcombo_r[0],
5432 169424 DoorComboSets[d].bombdoorcset_r[0]);
5433 338848 overcombo2(dest,x,y+16,
5434 169424 DoorComboSets[d].bombdoorcombo_r[1],
5435 169424 DoorComboSets[d].bombdoorcset_r[1]);
5436 338848 overcombo2(dest,x,y+16,
5437 169424 DoorComboSets[d].bombdoorcombo_r[2],
5438 169424 DoorComboSets[d].bombdoorcset_r[2]);
5439 169424 break;
5440 }
5441 706556 }
5442
5443 47568 void update_door(mapscr* scr, int32_t side, int32_t door, bool even_walls)
5444 {
5445
7/8
✓ Branch 0 taken 47460 times.
✓ Branch 1 taken 108 times.
✓ Branch 2 taken 47460 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22925 times.
✓ Branch 5 taken 24535 times.
✓ Branch 6 taken 530 times.
✓ Branch 7 taken 22395 times.
47568 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5446 25173 return;
5447
5448 int32_t doortype;
5449
5450
10/12
✓ Branch 0 taken 522 times.
✓ Branch 1 taken 655 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 12492 times.
✓ Branch 5 taken 910 times.
✓ Branch 6 taken 1553 times.
✓ Branch 7 taken 3192 times.
✓ Branch 8 taken 1694 times.
✓ Branch 9 taken 172 times.
✓ Branch 10 taken 67 times.
✓ Branch 11 taken 1138 times.
22395 switch(door)
5451 {
5452 case dWALL:
5453 doortype=dt_wall;
5454 break;
5455
5456 case dWALK:
5457 doortype=dt_walk;
5458 break;
5459
5460 case dOPEN:
5461 12492 doortype=dt_pass;
5462 12492 break;
5463
5464 case dLOCKED:
5465 910 doortype=dt_lock;
5466 910 break;
5467
5468 case dUNLOCKED:
5469 1553 doortype=dt_olck;
5470 1553 break;
5471
5472 case dSHUTTER:
5473
3/4
✓ Branch 0 taken 2783 times.
✓ Branch 1 taken 409 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2783 times.
3192 if(screenscrolling && ((HeroDir()^1)==side))
5474 {
5475 doortype=dt_osht;
5476 get_screen_state(scr->screen).open_doors = -4;
5477 break;
5478 }
5479
5480 [[fallthrough]];
5481 case d1WAYSHUTTER:
5482 3714 doortype=dt_shut;
5483 3714 break;
5484
5485 case dOPENSHUTTER:
5486 1694 doortype=dt_osht;
5487 1694 break;
5488
5489 case dBOSS:
5490 172 doortype=dt_boss;
5491 172 break;
5492
5493 case dOPENBOSS:
5494 67 doortype=dt_obos;
5495 67 break;
5496
5497 case dBOMBED:
5498 1138 doortype=dt_bomb;
5499 1138 break;
5500
5501 default:
5502 655 return;
5503 }
5504
5505
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 5629 times.
✓ Branch 2 taken 5770 times.
✓ Branch 3 taken 5111 times.
✓ Branch 4 taken 5230 times.
21740 switch(side)
5506 {
5507 case up:
5508 5629 put_door(scr,nullptr,7,side,doortype,false,even_walls);
5509 5629 break;
5510
5511 case down:
5512 5770 put_door(scr,nullptr,151,side,doortype,false,even_walls);
5513 5770 break;
5514
5515 case left:
5516 5111 put_door(scr,nullptr,64,side,doortype,false,even_walls);
5517 5111 break;
5518
5519 case right:
5520 5230 put_door(scr,nullptr,78,side,doortype,false,even_walls);
5521 5230 break;
5522 }
5523 47568 }
5524
5525 6504 void putdoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t door, bool redraw, bool even_walls)
5526 {
5527 /*
5528 #define dWALL 0 // 000 0
5529 #define dBOMB 6 // 011 0
5530 #define 8 // 100 0
5531 enum {dt_pass=0, dt_lock, dt_shut, dt_boss, dt_olck, dt_osht, dt_obos, dt_wall, dt_bomb, dt_walk, dt_max};
5532 */
5533
5534
7/8
✓ Branch 0 taken 6504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6500 times.
✓ Branch 3 taken 4 times.
✓ Branch 4 taken 6417 times.
✓ Branch 5 taken 83 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 6409 times.
6504 if(door == dNONE || (!even_walls&&(door==dWALL||door==dWALK)))
5535 91 return;
5536
5537 int32_t doortype;
5538
5539
8/12
✓ Branch 0 taken 227 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 362 times.
✓ Branch 7 taken 1530 times.
✓ Branch 8 taken 3958 times.
✓ Branch 9 taken 4 times.
✓ Branch 10 taken 51 times.
✓ Branch 11 taken 231 times.
6413 switch(door)
5540 {
5541 case dWALL:
5542 doortype=dt_wall;
5543 break;
5544
5545 case dWALK:
5546 doortype=dt_walk;
5547 break;
5548
5549 case dOPEN:
5550 50 doortype=dt_pass;
5551 50 break;
5552
5553 case dLOCKED:
5554 doortype=dt_lock;
5555 break;
5556
5557 case dUNLOCKED:
5558 362 doortype=dt_olck;
5559 362 break;
5560
5561 case dSHUTTER:
5562
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1530 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1530 if(screenscrolling && ((HeroDir()^1)==side))
5563 {
5564 doortype=dt_osht;
5565 get_screen_state(cur_screen).open_doors = -4;
5566 break;
5567 }
5568
5569 [[fallthrough]];
5570 case d1WAYSHUTTER:
5571 1757 doortype=dt_shut;
5572 1757 break;
5573
5574 case dOPENSHUTTER:
5575 3958 doortype=dt_osht;
5576 3958 break;
5577
5578 case dBOSS:
5579 4 doortype=dt_boss;
5580 4 break;
5581
5582 case dOPENBOSS:
5583 51 doortype=dt_obos;
5584 51 break;
5585
5586 case dBOMBED:
5587 231 doortype=dt_bomb;
5588 231 break;
5589
5590 default:
5591 return;
5592 }
5593
5594
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 1860 times.
✓ Branch 2 taken 1357 times.
✓ Branch 3 taken 1514 times.
✓ Branch 4 taken 1682 times.
6413 switch(side)
5595 {
5596 case up:
5597
2/2
✓ Branch 0 taken 1791 times.
✓ Branch 1 taken 69 times.
1860 switch(door)
5598 {
5599 case dBOMBED:
5600
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
138 if(redraw)
5601 {
5602 69 over_door(scr,dest,39,side,0,0);
5603 69 }
5604 [[fallthrough]];
5605 default:
5606 1860 put_door(scr,dest,7,side,doortype,redraw, even_walls);
5607 1860 break;
5608 }
5609
5610 1860 break;
5611
5612 case down:
5613
2/2
✓ Branch 0 taken 1318 times.
✓ Branch 1 taken 39 times.
1357 switch(door)
5614 {
5615 case dBOMBED:
5616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
78 if(redraw)
5617 {
5618 39 over_door(scr,dest,135,side,0,0);
5619 39 }
5620 [[fallthrough]];
5621 default:
5622 1357 put_door(scr,dest,151,side,doortype,redraw, even_walls);
5623 1357 break;
5624 }
5625
5626 1357 break;
5627
5628 case left:
5629
2/2
✓ Branch 0 taken 1463 times.
✓ Branch 1 taken 51 times.
1514 switch(door)
5630 {
5631 case dBOMBED:
5632
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51 times.
102 if(redraw)
5633 {
5634 51 over_door(scr,dest,66,side,0,0);
5635 51 }
5636 [[fallthrough]];
5637 default:
5638 1514 put_door(scr,dest,64,side,doortype,redraw, even_walls);
5639 1514 break;
5640 }
5641
5642 1514 break;
5643
5644 case right:
5645
2/2
✓ Branch 0 taken 1610 times.
✓ Branch 1 taken 72 times.
1682 switch(door)
5646 {
5647 case dBOMBED:
5648
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 72 times.
144 if(redraw)
5649 {
5650 72 over_door(scr,dest,77,side,0,0);
5651 72 }
5652 [[fallthrough]];
5653 default:
5654 1682 put_door(scr,dest,78,side,doortype,redraw, even_walls);
5655 1682 break;
5656 }
5657
5658 1682 break;
5659 }
5660 6504 }
5661
5662 586 void putcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5663 {
5664
1/2
✓ Branch 0 taken 586 times.
✗ Branch 1 not taken.
586 if(combo!=0)
5665 {
5666 586 putcombo(dest,x, y, combo, cset);
5667 586 }
5668 586 }
5669
5670 293 void overcombo_not_zero(BITMAP *dest, int32_t x, int32_t y, int32_t combo, int32_t cset)
5671 {
5672
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 74 times.
293 if(combo!=0)
5673 {
5674 219 overcombo(dest,x, y, combo, cset);
5675 219 }
5676 293 }
5677
5678 125 void showbombeddoor(mapscr* scr, BITMAP *dest, int32_t side, int32_t offx, int32_t offy)
5679 {
5680 125 int32_t d = scr->door_combo_set;
5681
5682
4/5
✗ Branch 0 not taken.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 37 times.
125 switch(side)
5683 {
5684 case up:
5685 86 putcombo_not_zero(dest,((7&15)<<4) + offx,(7&0xF0) + offy,
5686 43 DoorComboSets[d].doorcombo_u[dt_bomb][0],
5687 43 DoorComboSets[d].doorcset_u[dt_bomb][0]);
5688 86 putcombo_not_zero(dest,((8&15)<<4) + offx,(8&0xF0) + offy,
5689 43 DoorComboSets[d].doorcombo_u[dt_bomb][1],
5690 43 DoorComboSets[d].doorcset_u[dt_bomb][1]);
5691 86 putcombo_not_zero(dest,((23&15)<<4) + offx,(23&0xF0) + offy,
5692 43 DoorComboSets[d].doorcombo_u[dt_bomb][2],
5693 43 DoorComboSets[d].doorcset_u[dt_bomb][2]);
5694 86 putcombo_not_zero(dest,((24&15)<<4) + offx,(24&0xF0) + offy,
5695 43 DoorComboSets[d].doorcombo_u[dt_bomb][3],
5696 43 DoorComboSets[d].doorcset_u[dt_bomb][3]);
5697 86 overcombo_not_zero(dest,((39&15)<<4) + offx,(39&0xF0) + offy,
5698 43 DoorComboSets[d].bombdoorcombo_u[0],
5699 43 DoorComboSets[d].bombdoorcset_u[0]);
5700 86 overcombo_not_zero(dest,((40&15)<<4) + offx,(40&0xF0) + offy,
5701 43 DoorComboSets[d].bombdoorcombo_u[1],
5702 43 DoorComboSets[d].bombdoorcset_u[1]);
5703 43 break;
5704
5705 case down:
5706 78 putcombo_not_zero(dest,((151&15)<<4) + offx,(151&0xF0) + offy,
5707 39 DoorComboSets[d].doorcombo_d[dt_bomb][0],
5708 39 DoorComboSets[d].doorcset_d[dt_bomb][0]);
5709 78 putcombo_not_zero(dest,((152&15)<<4) + offx,(152&0xF0) + offy,
5710 39 DoorComboSets[d].doorcombo_d[dt_bomb][1],
5711 39 DoorComboSets[d].doorcset_d[dt_bomb][1]);
5712 78 putcombo_not_zero(dest,((167&15)<<4) + offx,(167&0xF0) + offy,
5713 39 DoorComboSets[d].doorcombo_d[dt_bomb][2],
5714 39 DoorComboSets[d].doorcset_d[dt_bomb][2]);
5715 78 putcombo_not_zero(dest,((168&15)<<4) + offx,(168&0xF0) + offy,
5716 39 DoorComboSets[d].doorcombo_d[dt_bomb][3],
5717 39 DoorComboSets[d].doorcset_d[dt_bomb][3]);
5718 78 overcombo_not_zero(dest,((135&15)<<4) + offx,(135&0xF0) + offy,
5719 39 DoorComboSets[d].bombdoorcombo_d[0],
5720 39 DoorComboSets[d].bombdoorcset_d[0]);
5721 78 overcombo_not_zero(dest,((136&15)<<4) + offx,(136&0xF0) + offy,
5722 39 DoorComboSets[d].bombdoorcombo_d[1],
5723 39 DoorComboSets[d].bombdoorcset_d[1]);
5724 39 break;
5725
5726 case left:
5727 12 putcombo_not_zero(dest,((64&15)<<4) + offx,(64&0xF0) + offy,
5728 6 DoorComboSets[d].doorcombo_l[dt_bomb][0],
5729 6 DoorComboSets[d].doorcset_l[dt_bomb][0]);
5730 12 putcombo_not_zero(dest,((65&15)<<4) + offx,(65&0xF0) + offy,
5731 6 DoorComboSets[d].doorcombo_l[dt_bomb][1],
5732 6 DoorComboSets[d].doorcset_l[dt_bomb][1]);
5733 12 putcombo_not_zero(dest,((80&15)<<4) + offx,(80&0xF0) + offy,
5734 6 DoorComboSets[d].doorcombo_l[dt_bomb][2],
5735 6 DoorComboSets[d].doorcset_l[dt_bomb][2]);
5736 12 putcombo_not_zero(dest,((81&15)<<4) + offx,(81&0xF0) + offy,
5737 6 DoorComboSets[d].doorcombo_l[dt_bomb][3],
5738 6 DoorComboSets[d].doorcset_l[dt_bomb][3]);
5739 12 putcombo_not_zero(dest,((96&15)<<4) + offx,(96&0xF0) + offy,
5740 6 DoorComboSets[d].doorcombo_l[dt_bomb][4],
5741 6 DoorComboSets[d].doorcset_l[dt_bomb][4]);
5742 12 putcombo_not_zero(dest,((97&15)<<4) + offx,(97&0xF0) + offy,
5743 6 DoorComboSets[d].doorcombo_l[dt_bomb][5],
5744 6 DoorComboSets[d].doorcset_l[dt_bomb][5]);
5745 12 overcombo_not_zero(dest,((66&15)<<4) + offx,(66&0xF0) + offy,
5746 6 DoorComboSets[d].bombdoorcombo_l[0],
5747 6 DoorComboSets[d].bombdoorcset_l[0]);
5748 12 overcombo_not_zero(dest,((82&15)<<4) + offx,(82&0xF0) + offy,
5749 6 DoorComboSets[d].bombdoorcombo_l[1],
5750 6 DoorComboSets[d].bombdoorcset_l[1]);
5751 12 overcombo_not_zero(dest,((98&15)<<4) + offx,(98&0xF0) + offy,
5752 6 DoorComboSets[d].bombdoorcombo_l[2],
5753 6 DoorComboSets[d].bombdoorcset_l[2]);
5754 6 break;
5755
5756 case right:
5757 74 putcombo_not_zero(dest,((78&15)<<4) + offx,(78&0xF0) + offy,
5758 37 DoorComboSets[d].doorcombo_r[dt_bomb][0],
5759 37 DoorComboSets[d].doorcset_r[dt_bomb][0]);
5760 74 putcombo_not_zero(dest,((79&15)<<4) + offx,(79&0xF0) + offy,
5761 37 DoorComboSets[d].doorcombo_r[dt_bomb][1],
5762 37 DoorComboSets[d].doorcset_r[dt_bomb][1]);
5763 74 putcombo_not_zero(dest,((94&15)<<4) + offx,(94&0xF0) + offy,
5764 37 DoorComboSets[d].doorcombo_r[dt_bomb][2],
5765 37 DoorComboSets[d].doorcset_r[dt_bomb][2]);
5766 74 putcombo_not_zero(dest,((95&15)<<4) + offx,(95&0xF0) + offy,
5767 37 DoorComboSets[d].doorcombo_r[dt_bomb][3],
5768 37 DoorComboSets[d].doorcset_r[dt_bomb][3]);
5769 74 putcombo_not_zero(dest,((110&15)<<4) + offx,(110&0xF0) + offy,
5770 37 DoorComboSets[d].doorcombo_r[dt_bomb][4],
5771 37 DoorComboSets[d].doorcset_r[dt_bomb][4]);
5772 74 putcombo_not_zero(dest,((111&15)<<4) + offx,(111&0xF0) + offy,
5773 37 DoorComboSets[d].doorcombo_r[dt_bomb][5],
5774 37 DoorComboSets[d].doorcset_r[dt_bomb][5]);
5775 74 overcombo_not_zero(dest,((77&15)<<4) + offx,(77&0xF0) + offy,
5776 37 DoorComboSets[d].bombdoorcombo_r[0],
5777 37 DoorComboSets[d].bombdoorcset_r[0]);
5778 74 overcombo_not_zero(dest,((93&15)<<4) + offx,(93&0xF0) + offy,
5779 37 DoorComboSets[d].bombdoorcombo_r[1],
5780 37 DoorComboSets[d].bombdoorcset_r[1]);
5781 74 overcombo_not_zero(dest,((109&15)<<4) + offx,(109&0xF0) + offy,
5782 37 DoorComboSets[d].bombdoorcombo_r[2],
5783 37 DoorComboSets[d].bombdoorcset_r[2]);
5784 37 break;
5785 }
5786 125 }
5787
5788 5357371 void openshutters(mapscr* scr)
5789 {
5790 5357371 bool opened_door = false;
5791
2/2
✓ Branch 0 taken 5357371 times.
✓ Branch 1 taken 21429484 times.
26786855 for(int32_t i=0; i<4; i++)
5792
2/2
✓ Branch 0 taken 21425526 times.
✓ Branch 1 taken 3958 times.
21433442 if(scr->door[i]==dSHUTTER)
5793 {
5794 3958 putdoor(scr, scrollbuf, i, dOPENSHUTTER);
5795 3958 scr->door[i]=dOPENSHUTTER;
5796 3958 opened_door = true;
5797 3958 }
5798
5799 5357371 auto& combo_cache = combo_caches::shutter;
5800 2020175719 for_every_combo_in_screen(create_screen_handles(scr), [&](const auto& handle) {
5801
3/4
✓ Branch 0 taken 2013207673 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 1610668 times.
✗ Branch 3 not taken.
2014818348 if (!combo_cache.minis[handle.data()].shutter)
5802 2014818341 return;
5803
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 trig_each_combo_trigger(handle, [&](combo_trigger const& trig){
5804 7 return trig.trigger_flags.get(TRIGFLAG_SHUTTER);
5805 });
5806 2014818348 });
5807
5808
2/2
✓ Branch 0 taken 5354640 times.
✓ Branch 1 taken 2731 times.
5357371 if(opened_door)
5809 2731 sfx(WAV_DOOR);
5810 5357371 }
5811
5812 15116782 void clear_darkroom_bitmaps()
5813 {
5814 15116782 clear_to_color(darkscr_bmp, game->get_darkscr_color());
5815 15116782 clear_to_color(darkscr_bmp_trans, game->get_darkscr_color());
5816 15116782 }
5817
5818 16031111 bool is_dark(const mapscr* scr)
5819 {
5820 16031111 bool dark = scr->flags&fDARK;
5821
2/2
✓ Branch 0 taken 3722 times.
✓ Branch 1 taken 16027389 times.
16031111 if (region_is_lit) return !dark;
5822 16027389 return dark;
5823 16031111 }
5824
5825 39226 bool scrolling_is_dark(const mapscr* scr)
5826 {
5827 39226 bool dark = scr->flags&fDARK;
5828
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 39224 times.
39226 if (scrolling_region_is_lit) return !dark;
5829 39224 return dark;
5830 39226 }
5831
5832 36758 bool is_any_dark()
5833 {
5834 36758 bool dark = false;
5835 74772 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
5836 38014 dark |= (bool)(is_dark(scr));
5837 38014 });
5838 36758 return dark;
5839 }
5840
5841 412 static mapscr prev_origin_scrs[7];
5842 412 static std::set<int> loadscr_ffc_script_ids_to_remove;
5843
5844 static void handle_screen_overlay(const std::vector<mapscr*>& screens)
5845 {
5846 mapscr* base_scr = screens[0];
5847 mapscr* previous_scr = &prev_origin_scrs[0];
5848
5849 for (int i = 0; i < 176; i++)
5850 {
5851 if (base_scr->data[i] == 0)
5852 {
5853 base_scr->data[i] = previous_scr->data[i];
5854 base_scr->sflag[i] = previous_scr->sflag[i];
5855 base_scr->cset[i] = previous_scr->cset[i];
5856 }
5857 }
5858
5859 for (int i = 0; i < 6; i++)
5860 {
5861 if (previous_scr->layermap[i] > 0 && base_scr->layermap[i] > 0)
5862 {
5863 int lm = (base_scr->layermap[i]-1)*MAPSCRS+base_scr->layerscreen[i];
5864 int fm = (previous_scr->layermap[i]-1)*MAPSCRS+previous_scr->layerscreen[i];
5865
5866 for (int j = 0; j < 176; j++)
5867 {
5868 if (TheMaps[lm].data[j] == 0)
5869 {
5870 TheMaps[lm].data[j] = TheMaps[fm].data[j];
5871 TheMaps[lm].sflag[j] = TheMaps[fm].sflag[j];
5872 TheMaps[lm].cset[j] = TheMaps[fm].cset[j];
5873 }
5874 }
5875 }
5876 }
5877
5878 for (int i = 1; i <= 6; i++)
5879 {
5880 mapscr* scr = screens[i];
5881 previous_scr = &prev_origin_scrs[i];
5882
5883 if (scr->layermap[i] > 0)
5884 {
5885 for (int y = 0; y < 11; y++)
5886 {
5887 for (int x = 0; x < 16; x++)
5888 {
5889 int c = y*16+x;
5890
5891 if (scr->data[c]==0)
5892 {
5893 scr->data[c] = previous_scr->data[c];
5894 scr->sflag[c] = previous_scr->sflag[c];
5895 scr->cset[c] = previous_scr->cset[c];
5896 }
5897 }
5898 }
5899 }
5900 }
5901 }
5902
5903 37098 static void load_a_screen_and_layers_init(int dmap, int screen, int ldir, bool screen_overlay, bool ffc_overlay)
5904 {
5905 37098 std::vector<mapscr*> screens;
5906
5907
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 const mapscr* source = get_canonical_scr(cur_map, screen);
5908
2/4
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37098 times.
✗ Branch 3 not taken.
37098 mapscr* base_scr = new mapscr(*source);
5909 37098 temporary_screens[screen*7] = base_scr;
5910
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 screens.push_back(base_scr);
5911
5912 37098 base_scr->valid |= mVALID; // layer 0 is always valid
5913
5914
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == cur_screen)
5915 35854 origin_scr = base_scr;
5916
2/2
✓ Branch 0 taken 1244 times.
✓ Branch 1 taken 35854 times.
37098 if (screen == hero_screen)
5917 35854 hero_scr = prev_hero_scr = base_scr;
5918
5919
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 36979 times.
37098 if (source->script > 0)
5920
1/2
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
119 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
5921
5922
2/2
✓ Branch 0 taken 37098 times.
✓ Branch 1 taken 222588 times.
259686 for (int i = 0; i < 6; i++)
5923 {
5924
2/2
✓ Branch 0 taken 173511 times.
✓ Branch 1 taken 49077 times.
222588 if(source->layermap[i]>0)
5925 {
5926
3/6
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49077 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 49077 times.
✗ Branch 5 not taken.
49077 mapscr* layer_scr = new mapscr(*get_canonical_scr(source->layermap[i]-1, source->layerscreen[i]));
5927 49077 layer_scr->map = cur_map;
5928 49077 layer_scr->screen = screen;
5929
1/2
✓ Branch 0 taken 49077 times.
✗ Branch 1 not taken.
49077 screens.push_back(layer_scr);
5930 49077 }
5931 else
5932 {
5933
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 mapscr* layer_scr = new mapscr();
5934 173511 layer_scr->map = cur_map;
5935 173511 layer_scr->screen = screen;
5936
1/2
✓ Branch 0 taken 173511 times.
✗ Branch 1 not taken.
173511 screens.push_back(layer_scr);
5937 }
5938 222588 temporary_screens[screen*7+i+1] = screens[i+1];
5939 222588 }
5940
5941
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
37098 if (screen_overlay)
5942 handle_screen_overlay(screens);
5943
5944
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 36954 times.
37098 if (ffc_overlay)
5945 {
5946 144 mapscr* previous_scr = &prev_origin_scrs[0];
5947
1/2
✓ Branch 0 taken 144 times.
✗ Branch 1 not taken.
144 int num_ffcs = previous_scr->numFFC();
5948
2/2
✓ Branch 0 taken 4608 times.
✓ Branch 1 taken 144 times.
4752 for (int i = 0; i < num_ffcs; i++)
5949 {
5950
2/2
✓ Branch 0 taken 4334 times.
✓ Branch 1 taken 274 times.
4608 if ((previous_scr->ffcs[i].flags&ffc_carryover))
5951 {
5952
2/4
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 274 times.
✗ Branch 3 not taken.
274 auto& ffc = base_scr->getFFC(i) = previous_scr->ffcs[i];
5953 274 ffc.screen_spawned = screen;
5954
5955
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 ffc_id_t ffc_id = get_region_screen_offset(screen)*MAXFFCS + i;
5956
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 loadscr_ffc_script_ids_to_remove.erase(ffc_id);
5957
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 274 times.
274 if (previous_scr->ffcs[i].flags&ffc_scriptreset)
5958 {
5959 FFCore.reset_script_engine_data(ScriptType::FFC, ffc_id);
5960 }
5961 274 }
5962 4608 }
5963 144 }
5964
5965
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
1141914 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
5966
1/2
✓ Branch 0 taken 37098 times.
✗ Branch 1 not taken.
37098 int num_ffcs = base_scr->numFFC();
5967
2/2
✓ Branch 0 taken 1104816 times.
✓ Branch 1 taken 37098 times.
1141914 for (word i = 0; i < num_ffcs; i++)
5968 {
5969 1104816 base_scr->ffcs[i].screen_spawned = screen;
5970
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].x += offx;
5971
1/2
✓ Branch 0 taken 1104816 times.
✗ Branch 1 not taken.
1104816 base_scr->ffcs[i].y += offy;
5972 1104816 }
5973 37098 }
5974
5975 37098 static void load_a_screen_and_layers_post(int dmap, int screen, int ldir)
5976 {
5977 37098 mapscr* base_scr = get_scr(screen);
5978 37098 int mi = mapind(cur_map, screen);
5979
5980 // Apply perm secrets, if applicable.
5981
2/2
✓ Branch 0 taken 11520 times.
✓ Branch 1 taken 25578 times.
37098 if (canPermSecret(dmap, screen))
5982 {
5983
2/2
✓ Branch 0 taken 23053 times.
✓ Branch 1 taken 2525 times.
25578 if(game->maps[mi] & mSECRET) // if special stuff done before
5984 {
5985 2525 reveal_hidden_stairs(base_scr, screen, false);
5986 2525 trigger_secrets_for_screen(TriggerSource::SecretsScreenState, base_scr, false);
5987 2525 }
5988
2/2
✓ Branch 0 taken 25575 times.
✓ Branch 1 taken 3 times.
25578 if(game->maps[mi] & mLIGHTBEAM) // if special stuff done before
5989 {
5990
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 for (int layer = 0; layer <= 6; layer++)
5991 {
5992 21 mapscr* layer_scr = get_scr_layer(screen, layer);
5993
2/2
✓ Branch 0 taken 3696 times.
✓ Branch 1 taken 21 times.
3717 for (int pos = 0; pos < 176; pos++)
5994 {
5995 3696 newcombo const* cmb = &combobuf[layer_scr->data[pos]];
5996
2/2
✓ Branch 0 taken 3693 times.
✓ Branch 1 taken 3 times.
3696 if(cmb->type == cLIGHTTARGET)
5997 {
5998
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!(cmb->usrflags&cflag1)) //Unlit version
5999 {
6000 3 layer_scr->data[pos] += 1;
6001 3 }
6002 3 }
6003 3696 }
6004 21 }
6005 3 }
6006 25578 }
6007
6008 37098 auto screen_handles = create_screen_handles(base_scr);
6009
6010 37098 int destlvl = DMaps[dmap].level;
6011 37098 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6012 37098 toggle_gswitches_load(screen_handles);
6013
6014 37098 bool should_check_for_state_things = (screen < 0x80);
6015
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 36191 times.
37098 if (should_check_for_state_things)
6016 {
6017
2/2
✓ Branch 0 taken 35819 times.
✓ Branch 1 taken 372 times.
36191 if (game->maps[mi]&mLOCKBLOCK)
6018 372 remove_lockblocks(screen_handles);
6019
2/2
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 58 times.
36191 if (game->maps[mi]&mBOSSLOCKBLOCK)
6020 58 remove_bosslockblocks(screen_handles);
6021
2/2
✓ Branch 0 taken 36035 times.
✓ Branch 1 taken 156 times.
36191 if (game->maps[mi]&mCHEST)
6022 156 remove_chests(screen_handles);
6023
1/2
✓ Branch 0 taken 36191 times.
✗ Branch 1 not taken.
36191 if (game->maps[mi]&mLOCKEDCHEST)
6024 remove_lockedchests(screen_handles);
6025
2/2
✓ Branch 0 taken 36180 times.
✓ Branch 1 taken 11 times.
36191 if (game->maps[mi]&mBOSSCHEST)
6026 11 remove_bosschests(screen_handles);
6027
6028 36191 clear_xdoors_mi(screen_handles, mi, true);
6029 36191 clear_xstatecombos_mi(screen_handles, mi, true);
6030 36191 }
6031
6032 // check doors
6033
2/2
✓ Branch 0 taken 25577 times.
✓ Branch 1 taken 11521 times.
37098 if (isdungeon(dmap, screen))
6034 {
6035
2/2
✓ Branch 0 taken 46084 times.
✓ Branch 1 taken 11521 times.
57605 for(int32_t i=0; i<4; i++)
6036 {
6037 46084 int32_t door=base_scr->door[i];
6038
6039
5/5
✓ Branch 0 taken 5303 times.
✓ Branch 1 taken 36475 times.
✓ Branch 2 taken 2372 times.
✓ Branch 3 taken 230 times.
✓ Branch 4 taken 1704 times.
46084 switch(door)
6040 {
6041 case d1WAYSHUTTER:
6042 case dSHUTTER:
6043
3/4
✓ Branch 0 taken 1694 times.
✓ Branch 1 taken 3609 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1694 times.
5303 if ((ldir^1)==i && screen == hero_screen)
6044 {
6045 1694 base_scr->door[i]=dOPENSHUTTER;
6046 1694 }
6047
6048 5303 get_screen_state(screen).open_doors = -4;
6049 5303 break;
6050
6051 case dLOCKED:
6052
3/4
✓ Branch 0 taken 2372 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1473 times.
✓ Branch 3 taken 899 times.
2372 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6053 {
6054 1473 base_scr->door[i]=dUNLOCKED;
6055 1473 }
6056
6057 2372 break;
6058
6059 case dBOSS:
6060
3/4
✓ Branch 0 taken 230 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 168 times.
230 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6061 {
6062 62 base_scr->door[i]=dOPENBOSS;
6063 62 }
6064
6065 230 break;
6066
6067 case dBOMB:
6068
3/4
✓ Branch 0 taken 1704 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1087 times.
✓ Branch 3 taken 617 times.
1704 if(should_check_for_state_things && game->maps[mi]&(mDOOR_UP<<i))
6069 {
6070 1087 base_scr->door[i]=dBOMBED;
6071 1087 }
6072
6073 1704 break;
6074 }
6075
6076 46084 update_door(base_scr, i, base_scr->door[i]);
6077
6078
4/4
✓ Branch 0 taken 41517 times.
✓ Branch 1 taken 4567 times.
✓ Branch 2 taken 736 times.
✓ Branch 3 taken 40781 times.
46084 if(door==dSHUTTER||door==d1WAYSHUTTER)
6079 {
6080 5303 base_scr->door[i]=door;
6081 5303 }
6082 46084 }
6083 11521 }
6084
6085
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 36961 times.
37098 if (!(base_scr->flags3 & fCYCLEONINIT))
6086 36961 return;
6087
6088
2/2
✓ Branch 0 taken 137 times.
✓ Branch 1 taken 959 times.
1096 for (int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6089 {
6090
4/4
✓ Branch 0 taken 822 times.
✓ Branch 1 taken 137 times.
✓ Branch 2 taken 377 times.
✓ Branch 3 taken 445 times.
959 if (j<0 || base_scr->layermap[j] > 0)
6091 {
6092 514 mapscr* layer_scr = get_scr_layer(screen, j + 1);
6093
3/4
✓ Branch 0 taken 377 times.
✓ Branch 1 taken 137 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 377 times.
514 mapscr* layerscreen= (j<0 ? base_scr : layer_scr->valid ? layer_scr :
6094 &TheMaps[(base_scr->layermap[j]-1)*MAPSCRS]+base_scr->layerscreen[j]);
6095
6096
2/2
✓ Branch 0 taken 90464 times.
✓ Branch 1 taken 514 times.
90978 for(int32_t i=0; i<176; ++i)
6097 {
6098 90464 int32_t c=layerscreen->data[i];
6099
6100 // New screen flag: Cycle Combos At Screen Init
6101
5/6
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 90399 times.
✓ Branch 2 taken 29 times.
✓ Branch 3 taken 36 times.
✓ Branch 4 taken 29 times.
✗ Branch 5 not taken.
90464 if(combobuf[c].nextcombo != 0 && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6102 {
6103 65 int32_t r = 0;
6104
6105
4/4
✓ Branch 0 taken 65 times.
✓ Branch 1 taken 84 times.
✓ Branch 2 taken 84 times.
✓ Branch 3 taken 65 times.
149 while(combobuf[c].can_cycle() && r++ < 10)
6106 {
6107 84 newcombo const& cmb = combobuf[c];
6108 84 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
84 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6110 84 layerscreen->data[i] = cid;
6111
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 69 times.
84 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6112
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 69 times.
69 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6113 84 c = layerscreen->data[i];
6114 }
6115 65 }
6116 90464 }
6117 514 }
6118 959 }
6119 37098 }
6120
6121 // Set `cur_screen` to `screen` and load new screens into temporary memory.
6122 //
6123 // Called anytime a player moves to a new screen (either via warping, scrolling, continue, starting
6124 // the game, etc...)
6125 //
6126 // Note: for regions, only the initial screen load calls this function. Simply walking between
6127 // screens in the same region does not use this, because every screen in a region is loaded into
6128 // temporary memory up front.
6129 //
6130 // If scr >= 0x80, `hero_screen` will be saved to `home_screen` and also be loaded into
6131 // `special_warp_return_scr`.
6132 //
6133 // If origin_screen_overlay is true, the old origin_scr combos will be copied to the new origin_scr combos
6134 // on all layers (but only where the new screen has a 0 combo).
6135 //
6136 // TODO: loadscr should set curdmap, but currently callers do that.
6137 35854 void loadscr(int32_t destdmap, int32_t screen, int32_t ldir, bool origin_screen_overlay, bool no_x80_dir)
6138 {
6139 35854 zapp_reporting_set_tag("screen", screen);
6140
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap != -1)
6141 8928 zapp_reporting_set_tag("dmap", destdmap);
6142
6143 35854 int32_t orig_destdmap = destdmap;
6144
2/2
✓ Branch 0 taken 8928 times.
✓ Branch 1 taken 26926 times.
35854 if (destdmap < 0) destdmap = cur_dmap;
6145
6146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35854 times.
35854 if (replay_is_active())
6147 {
6148
1/2
✓ Branch 0 taken 35854 times.
✗ Branch 1 not taken.
35854 if (replay_get_mode() == ReplayMode::ManualTakeover)
6149 replay_stop_manual_takeover();
6150
6151
2/2
✓ Branch 0 taken 26926 times.
✓ Branch 1 taken 8928 times.
35854 if (orig_destdmap != -1)
6152 {
6153
2/2
✓ Branch 0 taken 7857 times.
✓ Branch 1 taken 1071 times.
8928 if (strlen(DMaps[orig_destdmap].name) > 0)
6154 {
6155
1/2
✓ Branch 0 taken 7857 times.
✗ Branch 1 not taken.
7857 replay_step_comment(fmt::format("dmap={} {}", orig_destdmap, DMaps[orig_destdmap].name));
6156 7857 }
6157 else
6158 {
6159
1/2
✓ Branch 0 taken 1071 times.
✗ Branch 1 not taken.
1071 replay_step_comment(fmt::format("dmap={}", orig_destdmap));
6160 }
6161 8928 }
6162 35854 replay_step_comment_loadscr(screen);
6163
6164 // Reset the rngs and frame count so that recording steps can be modified without impacting
6165 // behavior of later screens.
6166 35854 replay_sync_rng();
6167 35854 }
6168
6169
2/2
✓ Branch 0 taken 1707536 times.
✓ Branch 1 taken 35854 times.
1743390 for (auto& state : get_screen_states())
6170 1707536 state.second.triggered_secrets = false;
6171 35854 slopes.clear();
6172 35854 Hero.clear_platform_ffc();
6173 35854 timeExitAllGenscript(GENSCR_ST_CHANGE_SCREEN);
6174 35854 clear_darkroom_bitmaps();
6175 35854 msgscr = nullptr;
6176
6177
2/2
✓ Branch 0 taken 50391860 times.
✓ Branch 1 taken 35854 times.
50427714 for (word x=0; x<animated_combos; x++)
6178 {
6179
2/2
✓ Branch 0 taken 20919990 times.
✓ Branch 1 taken 29471870 times.
50391860 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6180 {
6181 20919990 combobuf[animated_combo_table4[x][0]].aclk = 0;
6182 20919990 }
6183 50391860 }
6184 35854 reset_combo_animations2();
6185 35854 region_is_lit = false;
6186
6187 // Legacy features (combo and ffc overlays) may need the previous origin screens during loading
6188 // of the new ones.
6189 35854 bool origin_ffc_overlay = false;
6190
2/2
✓ Branch 0 taken 34717 times.
✓ Branch 1 taken 1137 times.
35854 if (origin_scr)
6191 {
6192
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 34715 times.
34717 if (!(origin_scr->flags5&fNOFFCARRYOVER))
6193 {
6194 34715 int c = origin_scr->numFFC();
6195
2/2
✓ Branch 0 taken 34571 times.
✓ Branch 1 taken 1038879 times.
1073450 for (int i = 0; i < c; i++)
6196 {
6197
2/2
✓ Branch 0 taken 1038735 times.
✓ Branch 1 taken 144 times.
1038879 if (origin_scr->ffcs[i].flags&ffc_carryover)
6198 {
6199 144 origin_ffc_overlay = true;
6200 144 break;
6201 }
6202 1038735 }
6203 34715 }
6204
6205
3/4
✓ Branch 0 taken 34717 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 144 times.
✓ Branch 3 taken 34573 times.
34717 if (origin_screen_overlay || origin_ffc_overlay)
6206 {
6207
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 144 times.
1152 for (int i = 0; i <= 6; i++)
6208 {
6209 1008 mapscr* prev_scr = get_scr_layer(cur_screen, i);
6210
1/2
✓ Branch 0 taken 1008 times.
✗ Branch 1 not taken.
1008 if (prev_scr)
6211 1008 prev_origin_scrs[i] = *prev_scr;
6212 else
6213 prev_origin_scrs[i] = {};
6214 1008 }
6215 144 }
6216 34717 }
6217
6218 // When loading a new screen, all previous FFC scripts end, with one exception.
6219 // Based on origin_ffc_overlay, some ffc scripts don't get reset. This set starts with all of
6220 // them, but scripts that need their data to persist will be removed.
6221 35854 loadscr_ffc_script_ids_to_remove.clear();
6222
2/2
✓ Branch 0 taken 74698175 times.
✓ Branch 1 taken 35854 times.
74734029 for (auto& key : scriptEngineDatas | std::views::keys)
6223 {
6224
2/2
✓ Branch 0 taken 73576270 times.
✓ Branch 1 taken 1121905 times.
74698175 if (key.first == ScriptType::FFC)
6225 1121905 loadscr_ffc_script_ids_to_remove.insert(key.second);
6226 }
6227
6228 35854 load_region(destdmap, screen);
6229
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 34947 times.
35854 home_screen = screen >= 0x80 ? hero_screen : cur_screen;
6230 35854 hero_screen = screen;
6231
6232 35854 cpos_clear_all();
6233 35854 FFCore.destroyScriptableObjectsOfType(ScriptType::Screen);
6234 35854 FFCore.clear_combo_scripts();
6235
6236
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6237 {
6238
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6239 {
6240
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6241 {
6242
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool screen_overlay = origin_screen_overlay && screen == cur_screen;
6243
1/2
✓ Branch 0 taken 1408 times.
✗ Branch 1 not taken.
1408 bool ffc_overlay = origin_ffc_overlay && screen == cur_screen;
6244 1408 load_a_screen_and_layers_init(destdmap, screen, ldir, screen_overlay, ffc_overlay);
6245 1408 }
6246 20992 }
6247 164 }
6248 else
6249 {
6250 35690 load_a_screen_and_layers_init(destdmap, screen, ldir, origin_screen_overlay, origin_ffc_overlay);
6251 }
6252
6253 35854 prepare_current_region_handles();
6254
6255
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 35690 times.
35854 if (is_in_scrolling_region())
6256 {
6257
2/2
✓ Branch 0 taken 20992 times.
✓ Branch 1 taken 164 times.
21156 for (int screen = 0; screen < 128; screen++)
6258 {
6259
2/2
✓ Branch 0 taken 19584 times.
✓ Branch 1 taken 1408 times.
20992 if (is_in_current_region(screen))
6260 {
6261 1408 load_a_screen_and_layers_post(destdmap, screen, ldir);
6262 1408 }
6263 20992 }
6264 164 }
6265 else
6266 {
6267 35690 load_a_screen_and_layers_post(destdmap, screen, ldir);
6268 }
6269
6270 // If on a special screen, load the screen the player is currently on (home_screen) into special_warp_return_scr.
6271
2/2
✓ Branch 0 taken 34947 times.
✓ Branch 1 taken 907 times.
35854 if (screen >= 0x80)
6272
2/2
✓ Branch 0 taken 476 times.
✓ Branch 1 taken 431 times.
907 loadscr_old(orig_destdmap, home_screen, no_x80_dir ? -1 : ldir, origin_screen_overlay);
6273
6274 35854 update_slope_comboposes();
6275 35854 cpos_force_update();
6276 35854 trig_trigger_groups();
6277
6278
2/2
✓ Branch 0 taken 1121631 times.
✓ Branch 1 taken 35854 times.
1157485 for (int index : loadscr_ffc_script_ids_to_remove)
6279 {
6280 // Note: ideally would use "destroySprite", but during scrolling the previous
6281 // screen's FFCs are still accessible (even though only the new screen's FFC scripts run).
6282 // The only difference is a call to "release_sprite_owned_objects". To defer FFC script
6283 // owned objects being released until the end of the scroll, here "destroyScriptableObject"
6284 // is used instead.
6285 //
6286 // So when is "release_sprite_owned_objects" called for FFCs? For scrolling screen
6287 // transitions, it's at the end of "scrollscr" via "delete_temporary_screens". Otherwise,
6288 // it is called above when "load_region" calls "clear_temporary_screens".
6289 1121631 FFCore.destroyScriptableObject(ScriptType::FFC, index);
6290 }
6291
6292 // "extended height mode" includes the top 56 pixels as part of the visible mapscr viewport,
6293 // allowing for regions to display 4 more rows of combos (as many as ALTTP does). This part of
6294 // screen is normally reserved for the passive subscreen, but in this mode mapscr combos are drawn below it.
6295 // It is up to the quest designer to make their subscreen be actually transparent.
6296 //
6297 // When not in "extended height mode" (otherwise 56 is 0):
6298 // - playing_field_offset: 56, but changes during earthquakes
6299 // - original_playing_field_offset: always 56
6300 //
6301 // These values are used to adjust where things are drawn on screen to account for the passive subscreen. Examples:
6302 // - yofs of sprites
6303 // - bitmap y offsets in draw_screen
6304 // - drawing offsets for putscr, do_layer
6305 // - drawing offsets for various calls to overtile16 (see bomb weapon explosion)
6306 // - lots more
6307 //
6308 // TODO: consider refactor of yofs, make yofs start as 0 by default and add playing_field_offset at draw time?
6309
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 35712 times.
35854 if (is_extended_height_mode())
6310 {
6311 142 playing_field_offset = 0;
6312 142 original_playing_field_offset = 0;
6313 // A few sprites exist as globals, so we must manually reset them.
6314 142 Hero.yofs = 0;
6315 142 mblock2.yofs = 0;
6316 142 }
6317 else
6318 {
6319 35712 mblock2.yofs = Hero.yofs = playing_field_offset = 56;
6320 35712 original_playing_field_offset = 56;
6321 }
6322 35854 is_any_room_dark = is_any_dark();
6323
6324 35854 game->load_portal();
6325 35854 throwGenScriptEvent(GENSCR_EVENT_CHANGE_SCREEN);
6326
3/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 35819 times.
✓ Branch 2 taken 35 times.
✗ Branch 3 not taken.
35854 if (Hero.lift_wpn && get_qr(qr_CARRYABLE_NO_ACROSS_SCREEN))
6327 {
6328 delete Hero.lift_wpn;
6329 Hero.lift_wpn = nullptr;
6330 }
6331
6332 35854 enemy_spawning_has_checked_been_here = false;
6333 35854 markBmap(-1, hero_screen);
6334 35854 Hero.maybe_begin_advanced_maze();
6335 35854 }
6336
6337 // Don't use this directly! Use `loadscr` instead.
6338 907 void loadscr_old(int32_t destdmap, int32_t screen,int32_t ldir,bool overlay)
6339 {
6340
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int32_t destlvl = DMaps[destdmap < 0 ? cur_dmap : destdmap].level;
6341
6342 907 mapscr previous_scr = *special_warp_return_scr;
6343 907 mapscr* scr = special_warp_return_scr;
6344
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 const mapscr* source = get_canonical_scr(cur_map, screen);
6345
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 *scr = *source;
6346
6347
2/2
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 907 times.
6349 for (int i = 1; i <= 6; i++)
6348 {
6349
2/2
✓ Branch 0 taken 383 times.
✓ Branch 1 taken 5059 times.
5442 if (scr->layermap[i-1] > 0)
6350
2/4
✓ Branch 0 taken 383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383 times.
✗ Branch 3 not taken.
383 special_warp_return_scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6351 else
6352 5059 special_warp_return_scrs[i] = {};
6353 5442 }
6354
6355 907 scr->valid |= mVALID; //layer 0 is always valid
6356
6357
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 907 times.
907 if ( source->script > 0 )
6358 {
6359 scr->script = source->script;
6360 for ( int32_t q = 0; q < 8; q++ )
6361 {
6362 scr->screeninitd[q] = source->screeninitd[q];
6363 }
6364 FFCore.reset_script_engine_data(ScriptType::Screen, screen);
6365 }
6366 else
6367 {
6368 907 scr->script = 0;
6369 }
6370
6371
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 if(overlay)
6372 {
6373 for(int32_t c=0; c< 176; ++c)
6374 {
6375 if(scr->data[c]==0)
6376 {
6377 scr->data[c]=previous_scr.data[c];
6378 scr->sflag[c]=previous_scr.sflag[c];
6379 scr->cset[c]=previous_scr.cset[c];
6380 }
6381 }
6382
6383 for(int32_t i=0; i<6; i++)
6384 {
6385 if(previous_scr.layermap[i]>0 && scr->layermap[i]>0)
6386 {
6387 int32_t lm = (scr->layermap[i]-1)*MAPSCRS+scr->layerscreen[i];
6388 int32_t fm = (previous_scr.layermap[i]-1)*MAPSCRS+previous_scr.layerscreen[i];
6389
6390 for(int32_t c=0; c< 176; ++c)
6391 {
6392 if(TheMaps[lm].data[c]==0)
6393 {
6394 TheMaps[lm].data[c] = TheMaps[fm].data[c];
6395 TheMaps[lm].sflag[c] = TheMaps[fm].sflag[c];
6396 TheMaps[lm].cset[c] = TheMaps[fm].cset[c];
6397 }
6398 }
6399 }
6400 }
6401 }
6402
6403
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
29900 auto [offx, offy] = translate_screen_coordinates_to_world(screen);
6404
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 int c = scr->numFFC();
6405
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 28993 times.
29900 for (word i = 0; i < c; i++)
6406 {
6407 28993 scr->ffcs[i].screen_spawned = screen;
6408
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].x += offx;
6409
1/2
✓ Branch 0 taken 28993 times.
✗ Branch 1 not taken.
28993 scr->ffcs[i].y += offy;
6410 28993 }
6411
6412 907 int mi = mapind(cur_map, screen);
6413
6414 // Apply perm secrets, if applicable.
6415
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✓ Branch 3 taken 371 times.
907 if(canPermSecret(destdmap,screen))
6416 {
6417
3/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 332 times.
536 if(game->maps[mi]&mSECRET) // if special stuff done before
6418 {
6419
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 reveal_hidden_stairs(scr, screen, false);
6420
6421
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 log_trigger_secret_reason(TriggerSource::SecretsScreenState);
6422
1/2
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
204 get_screen_state(special_warp_return_scr->screen).triggered_secrets = true;
6423 204 bool do_replay_comment = true;
6424 204 bool from_active_screen = false;
6425
2/4
✓ Branch 0 taken 204 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 204 times.
✗ Branch 3 not taken.
204 trigger_secrets_for_screen_internal(create_screen_handles(special_warp_return_scr), from_active_screen, false, -1, do_replay_comment);
6426 204 }
6427
2/4
✓ Branch 0 taken 536 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 536 times.
✗ Branch 3 not taken.
536 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6428 {
6429 for (int layer = 0; layer <= 6; layer++)
6430 {
6431 mapscr* tscr = &special_warp_return_scrs[layer];
6432 for (int pos = 0; pos < 176; pos++)
6433 {
6434 newcombo const* cmb = &combobuf[tscr->data[pos]];
6435 if(cmb->type == cLIGHTTARGET)
6436 {
6437 if(!(cmb->usrflags&cflag1)) //Unlit version
6438 {
6439 tscr->data[pos] += 1;
6440 }
6441 }
6442 }
6443 }
6444 }
6445 536 }
6446
6447 screen_handles_t screen_handles;
6448
2/2
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 6349 times.
7256 for (int i = 0; i <= 6; i++)
6449
3/4
✓ Branch 0 taken 6349 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1289 times.
✓ Branch 3 taken 5060 times.
6349 screen_handles[i] = {scr, special_warp_return_scrs[i].is_valid() ? &special_warp_return_scrs[i] : nullptr, screen, i};
6450
6451
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 907 times.
✗ Branch 3 not taken.
907 toggle_switches(game->lvlswitches[destlvl], true, screen_handles);
6452
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 toggle_gswitches_load(screen_handles);
6453
6454
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 902 times.
907 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6455 {
6456
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 remove_lockblocks(screen_handles);
6457 5 }
6458
6459
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 906 times.
907 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6460 {
6461
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6462 1 }
6463
6464
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mCHEST) // if special stuff done before
6465 {
6466 remove_chests(screen_handles);
6467 }
6468
6469
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6470 {
6471 remove_lockedchests(screen_handles);
6472 }
6473
6474
2/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 907 times.
907 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6475 {
6476 remove_bosschests(screen_handles);
6477 }
6478
6479
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xdoors(screen_handles, true);
6480
1/2
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
907 clear_xstatecombos(screen_handles, true);
6481
6482 // check doors
6483
3/4
✓ Branch 0 taken 907 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 371 times.
✓ Branch 3 taken 536 times.
907 if (isdungeon(destdmap, screen))
6484 {
6485
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 371 times.
1855 for(int32_t i=0; i<4; i++)
6486 {
6487 1484 int32_t door=scr->door[i];
6488
6489
4/4
✓ Branch 0 taken 91 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 89 times.
✓ Branch 3 taken 1295 times.
1484 switch(door)
6490 {
6491 case d1WAYSHUTTER:
6492 case dSHUTTER:
6493
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 1295 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
1295 if ((ldir^1)==i && screen == home_screen)
6494 {
6495 scr->door[i]=dOPENSHUTTER;
6496 }
6497
6498
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1190 times.
1295 get_screen_state(screen).open_doors = -4;
6499 105 break;
6500
6501 case dLOCKED:
6502
3/4
✓ Branch 0 taken 91 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 80 times.
✓ Branch 3 taken 11 times.
91 if(game->maps[mi]&(mDOOR_UP<<i))
6503 {
6504 80 scr->door[i]=dUNLOCKED;
6505 80 }
6506
6507 91 break;
6508
6509 case dBOSS:
6510
3/4
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 4 times.
9 if(game->maps[mi]&(mDOOR_UP<<i))
6511 {
6512 5 scr->door[i]=dOPENBOSS;
6513 5 }
6514
6515 9 break;
6516
6517 case dBOMB:
6518
3/4
✓ Branch 0 taken 89 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 51 times.
✓ Branch 3 taken 38 times.
89 if(game->maps[mi]&(mDOOR_UP<<i))
6519 {
6520 51 scr->door[i]=dBOMBED;
6521 51 }
6522
6523 89 break;
6524 }
6525
6526
2/2
✓ Branch 0 taken 1484 times.
✓ Branch 1 taken 1190 times.
294 update_door(scr, i, scr->door[i]);
6527
6528
4/4
✓ Branch 0 taken 1390 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1379 times.
1484 if(door==dSHUTTER||door==d1WAYSHUTTER)
6529 {
6530 105 scr->door[i]=door;
6531 105 }
6532 1484 }
6533 371 }
6534
6535
2/2
✓ Branch 0 taken 6915 times.
✓ Branch 1 taken 549 times.
7256 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6536 {
6537
4/4
✓ Branch 0 taken 5442 times.
✓ Branch 1 taken 1473 times.
✓ Branch 2 taken 2763 times.
✓ Branch 3 taken 2679 times.
6915 if (j<0 || scr->layermap[j] > 0)
6538 {
6539
4/4
✓ Branch 0 taken 907 times.
✓ Branch 1 taken 383 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 1 times.
4236 mapscr *layerscreen= (j<0 ? scr : special_warp_return_scrs[j+1].valid ? &special_warp_return_scrs[j+1] :
6540 1 &TheMaps[(scr->layermap[j]-1)*MAPSCRS]+scr->layerscreen[j]);
6541
6542
2/2
✓ Branch 0 taken 224660 times.
✓ Branch 1 taken 3670 times.
228330 for(int32_t i=0; i<176; ++i)
6543 {
6544 224660 int32_t c=layerscreen->data[i];
6545
6546 // New screen flag: Cycle Combos At Screen Init
6547
5/8
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 224654 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2380 times.
✓ Branch 7 taken 2380 times.
224660 if(combobuf[c].nextcombo != 0 && (scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6548 {
6549 2380 int32_t r = 0;
6550
6551
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 2380 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2380 while(combobuf[c].can_cycle() && r++ < 10)
6552 {
6553 newcombo const& cmb = combobuf[c];
6554 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6555 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6556 layerscreen->data[i] = cid;
6557 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6558 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6559 c = layerscreen->data[i];
6560 }
6561 }
6562 227040 }
6563 3670 }
6564 6349 }
6565 5309 }
6566
6567 // Load screen (and layers). Unlike loadscr, this doesn't load to the global temporary_screens, but
6568 // instead returns an array of mapscr.
6569 // Used to draw/save the map.
6570 45680 std::array<mapscr, 7> loadscr2(int32_t screen)
6571 {
6572 45680 std::array<mapscr, 7> scrs;
6573 45680 mapscr* scr = &scrs[0];
6574
6575
2/2
✓ Branch 0 taken 64716181 times.
✓ Branch 1 taken 45680 times.
64761861 for(word x=0; x<animated_combos; x++)
6576 {
6577
2/2
✓ Branch 0 taken 31963685 times.
✓ Branch 1 taken 32752496 times.
64716181 if(combobuf[animated_combo_table4[x][0]].nextcombo!=0)
6578 {
6579 32752496 combobuf[animated_combo_table4[x][0]].aclk=0;
6580 32752496 }
6581 64716181 }
6582
6583
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 const mapscr* source = get_canonical_scr(cur_map, screen);
6584
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!source->is_valid())
6585 {
6586 scrs[0].valid = 0;
6587 return scrs;
6588 }
6589
6590
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 *scr = *get_canonical_scr(cur_map, screen);
6591
2/2
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
319760 for (int i = 1; i <= 6; i++)
6592 {
6593
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 209266 times.
274080 if (scr->layermap[i-1] > 0)
6594
2/4
✓ Branch 0 taken 64814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 64814 times.
✗ Branch 3 not taken.
64814 scrs[i] = *get_canonical_scr(scr->layermap[i-1] - 1, scr->layerscreen[i-1]);
6595 else
6596 209266 scrs[i] = {};
6597 274080 }
6598
6599 screen_handles_t screen_handles;
6600
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i < 7; i++)
6601
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
6602
6603 45680 int mi = mapind(cur_map, screen);
6604
6605
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45626 times.
✓ Branch 3 taken 54 times.
45680 if(canPermSecret(-1,screen))
6606 {
6607
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5730 times.
✓ Branch 3 taken 39896 times.
45626 if(game->maps[mi]&mSECRET) // if special stuff done before
6608 {
6609
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 reveal_hidden_stairs(scr, screen, false);
6610 5730 bool from_active_screen = false;
6611 5730 bool do_replay_comment = true;
6612
1/2
✓ Branch 0 taken 5730 times.
✗ Branch 1 not taken.
5730 trigger_secrets_for_screen_internal(screen_handles, from_active_screen, false, -1, do_replay_comment);
6613 5730 }
6614
3/4
✓ Branch 0 taken 45626 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45609 times.
✓ Branch 3 taken 17 times.
45626 if(game->maps[mi]&mLIGHTBEAM) // if special stuff done before
6615 {
6616
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 17 times.
136 for (int layer = 0; layer <= 6; layer++)
6617 {
6618 119 mapscr* tscr = &scrs[layer];
6619
2/2
✓ Branch 0 taken 20944 times.
✓ Branch 1 taken 119 times.
21063 for (int pos = 0; pos < 176; pos++)
6620 {
6621 20944 newcombo const* cmb = &combobuf[tscr->data[pos]];
6622
2/2
✓ Branch 0 taken 20927 times.
✓ Branch 1 taken 17 times.
20944 if(cmb->type == cLIGHTTARGET)
6623 {
6624
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if(!(cmb->usrflags&cflag1)) //Unlit version
6625 {
6626 17 tscr->data[pos] += 1;
6627 17 }
6628 17 }
6629 20944 }
6630 119 }
6631 17 }
6632 45626 }
6633
6634
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 233 times.
✓ Branch 3 taken 45447 times.
45680 if(game->maps[mi]&mLOCKBLOCK) // if special stuff done before
6635 {
6636
1/2
✓ Branch 0 taken 233 times.
✗ Branch 1 not taken.
233 remove_lockblocks(screen_handles);
6637 233 }
6638
6639
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 45679 times.
45680 if(game->maps[mi]&mBOSSLOCKBLOCK) // if special stuff done before
6640 {
6641
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 remove_bosslockblocks(screen_handles);
6642 1 }
6643
6644
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 101 times.
✓ Branch 3 taken 45579 times.
45680 if(game->maps[mi]&mCHEST) // if special stuff done before
6645 {
6646
1/2
✓ Branch 0 taken 101 times.
✗ Branch 1 not taken.
101 remove_chests(screen_handles);
6647 101 }
6648
6649
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 45656 times.
45680 if(game->maps[mi]&mLOCKEDCHEST) // if special stuff done before
6650 {
6651
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 remove_lockedchests(screen_handles);
6652 24 }
6653
6654
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(game->maps[mi]&mBOSSCHEST) // if special stuff done before
6655 {
6656 remove_bosschests(screen_handles);
6657 }
6658
6659
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xdoors(screen_handles);
6660
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 clear_xstatecombos(screen_handles);
6661
6662 // check doors
6663
3/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 45626 times.
45680 if (isdungeon(screen))
6664 {
6665
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 54 times.
270 for(int32_t i=0; i<4; i++)
6666 {
6667 216 int32_t door=scr->door[i];
6668 216 bool putit=true;
6669
6670
4/5
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 61 times.
✓ Branch 4 taken 139 times.
216 switch(door)
6671 {
6672 case d1WAYSHUTTER:
6673 case dSHUTTER:
6674 61 break;
6675
6676 case dLOCKED:
6677
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12 times.
12 if(game->maps[mi]&(mDOOR_UP<<i))
6678 {
6679 12 scr->door[i]=dUNLOCKED;
6680 12 }
6681
6682 12 break;
6683
6684 case dBOSS:
6685
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
4 if(game->maps[mi]&(mDOOR_UP<<i))
6686 {
6687 scr->door[i]=dOPENBOSS;
6688 }
6689
6690 4 break;
6691
6692 case dBOMB:
6693 if(game->maps[mi]&(mDOOR_UP<<i))
6694 {
6695 scr->door[i]=dBOMBED;
6696 }
6697
6698 break;
6699 }
6700
6701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 216 times.
216 if(putit)
6702 {
6703
1/2
✓ Branch 0 taken 216 times.
✗ Branch 1 not taken.
216 putdoor(scr, scrollbuf, i, scr->door[i], false);
6704 216 }
6705
6706
3/4
✓ Branch 0 taken 155 times.
✓ Branch 1 taken 61 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 155 times.
216 if(door==dSHUTTER||door==d1WAYSHUTTER)
6707 {
6708 61 scr->door[i]=door;
6709 61 }
6710 216 }
6711 54 }
6712
6713
2/2
✓ Branch 0 taken 319760 times.
✓ Branch 1 taken 45680 times.
365440 for(int32_t j=-1; j<6; ++j) // j == -1 denotes the current screen
6714 {
6715
4/4
✓ Branch 0 taken 274080 times.
✓ Branch 1 taken 45680 times.
✓ Branch 2 taken 64814 times.
✓ Branch 3 taken 209266 times.
319760 if (j < 0 || scr->layermap[j] > 0)
6716 {
6717
2/2
✓ Branch 0 taken 64814 times.
✓ Branch 1 taken 45680 times.
110494 mapscr *layerscreen= (j<0 ? scr
6718 64814 : &(TheMaps[(scr->layermap[j]-1)*MAPSCRS+scr->layerscreen[j]]));
6719
6720
2/2
✓ Branch 0 taken 19446944 times.
✓ Branch 1 taken 110494 times.
19557438 for(int32_t i=0; i<176; ++i)
6721 {
6722 19446944 int32_t c=layerscreen->data[i];
6723
6724 // New screen flag: Cycle Combos At Screen Init
6725
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 19446944 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
19446944 if((scr->flags3 & fCYCLEONINIT) && (j<0 || get_qr(qr_CMBCYCLELAYERS)))
6726 {
6727 int32_t r = 0;
6728
6729 while(combobuf[c].can_cycle() && r++ < 10)
6730 {
6731 newcombo const& cmb = combobuf[c];
6732 bool cycle_under = (cmb.animflags & AF_CYCLEUNDERCOMBO);
6733 auto cid = cycle_under ? layerscreen->undercombo : cmb.nextcombo;
6734 layerscreen->data[i] = cid;
6735 if(!(combobuf[c].animflags & AF_CYCLENOCSET))
6736 layerscreen->cset[i] = cycle_under ? layerscreen->undercset : cmb.nextcset;
6737 c = layerscreen->data[i];
6738 }
6739 }
6740 19446944 }
6741 110494 }
6742 319760 }
6743
6744 45680 return scrs;
6745
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 }
6746
6747 19016051 void putscr(mapscr* scr, BITMAP* dest, int32_t x, int32_t y)
6748 {
6749 // This is a bogus value while screenscrolling == true, but that's ok
6750 // because it is only used to calculate the rpos, and during screenscrolling
6751 // only the modulus to get pos (draw_cmb_pos does RPOS_TO_POS) is needed, which
6752 // is always the same no matter the value of scr.
6753 19016051 int screen = get_screen_for_world_xy(x, y);
6754
6755 19016051 x -= viewport.x;
6756 19016051 y -= viewport.y;
6757
6758
3/6
✓ Branch 0 taken 19016051 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19016051 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 19016051 times.
19016051 if (!scr->is_valid()||!show_layers[0]||scr->hidelayers & 1)
6759 {
6760 rectfill(dest,x,y,x+255,y+175,0);
6761 return;
6762 }
6763
6764 37903193 bool over = XOR(scr->flags7&fLAYER2BG,DMaps[cur_dmap].flags&dmfLAYER2BG)
6765
2/2
✓ Branch 0 taken 128909 times.
✓ Branch 1 taken 18887142 times.
19016051 || XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG);
6766
6767 int start_x, end_x, start_y, end_y;
6768 19016051 get_bounds_for_draw_cmb_calls(dest, x, y, start_x, end_x, start_y, end_y);
6769
2/2
✓ Branch 0 taken 19016051 times.
✓ Branch 1 taken 202549048 times.
221565099 for (int cy = start_y; cy < end_y; cy++)
6770 {
6771
2/2
✓ Branch 0 taken 3075834962 times.
✓ Branch 1 taken 202549048 times.
3278384010 for (int cx = start_x; cx < end_x; cx++)
6772 {
6773 3075834962 int i = cx + cy*16;
6774
2/2
✓ Branch 0 taken 357850966 times.
✓ Branch 1 taken 2717983996 times.
3075834962 auto rpos = screenscrolling ? rpos_t::None : POS_TO_RPOS(i, screen);
6775 3075834962 draw_cmb_pos(dest, x + cx*16, y + cy*16, rpos, scr->data[i], scr->cset[i], 0, over, false);
6776 3075834962 }
6777 202549048 }
6778 19016051 }
6779
6780 15539765 static void putscrdoors(const nearby_screens_t& nearby_screens, BITMAP *dest, int32_t x, int32_t y)
6781 {
6782
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
15539765 if (!show_layers[0])
6783 {
6784 return;
6785 }
6786
6787 15539765 x -= viewport.x;
6788 15539765 y -= viewport.y;
6789
6790
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15539765 times.
31215848 for_every_nearby_screen(nearby_screens, [&](screen_handles_t screen_handles, int screen, int offx, int offy) {
6791 15676083 mapscr* scr = screen_handles[0].base_scr;
6792
1/2
✓ Branch 0 taken 15676083 times.
✗ Branch 1 not taken.
15676083 if (!scr->is_valid())
6793 return;
6794
6795
2/2
✓ Branch 0 taken 123411 times.
✓ Branch 1 taken 15552672 times.
15676083 if(scr->door[0]==dBOMBED)
6796 {
6797 123411 over_door(scr, dest, 39, up, offx+x, offy+y);
6798 123411 }
6799
6800
2/2
✓ Branch 0 taken 143109 times.
✓ Branch 1 taken 15532974 times.
15676083 if(scr->door[1]==dBOMBED)
6801 {
6802 143109 over_door(scr, dest, 135, down, offx+x, offy+y);
6803 143109 }
6804
6805
2/2
✓ Branch 0 taken 155862 times.
✓ Branch 1 taken 15520221 times.
15676083 if(scr->door[2]==dBOMBED)
6806 {
6807 155862 over_door(scr, dest, 66, left, offx+x, offy+y);
6808 155862 }
6809
6810
2/2
✓ Branch 0 taken 132289 times.
✓ Branch 1 taken 15543794 times.
15676083 if(scr->door[3]==dBOMBED)
6811 {
6812 132289 over_door(scr, dest, 77, right, offx+x, offy+y);
6813 132289 }
6814 15676083 });
6815 15539765 }
6816
6817 3339968 void putscrdoors(mapscr* scr, BITMAP *dest, int32_t x, int32_t y)
6818 {
6819
2/4
✓ Branch 0 taken 3339968 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3339968 times.
✗ Branch 3 not taken.
3339968 if (!scr->is_valid() || !show_layers[0])
6820 return;
6821
6822 3339968 x -= viewport.x;
6823 3339968 y -= viewport.y;
6824
6825
2/2
✓ Branch 0 taken 37656 times.
✓ Branch 1 taken 3302312 times.
3339968 if(scr->door[0]==dBOMBED)
6826 {
6827 37656 over_door(scr,dest,39,up,x,y);
6828 37656 }
6829
6830
2/2
✓ Branch 0 taken 36495 times.
✓ Branch 1 taken 3303473 times.
3339968 if(scr->door[1]==dBOMBED)
6831 {
6832 36495 over_door(scr,dest,135,down,x,y);
6833 36495 }
6834
6835
2/2
✓ Branch 0 taken 40440 times.
✓ Branch 1 taken 3299528 times.
3339968 if(scr->door[2]==dBOMBED)
6836 {
6837 40440 over_door(scr,dest,66,left,x,y);
6838 40440 }
6839
6840
2/2
✓ Branch 0 taken 37063 times.
✓ Branch 1 taken 3302905 times.
3339968 if(scr->door[3]==dBOMBED)
6841 {
6842 37063 over_door(scr,dest,77,right,x,y);
6843 37063 }
6844 3339968 }
6845 232437410 static inline bool standing_on_z(newcombo const& cmb, zfix const& standing_z_state)
6846 {
6847 232437410 zfix cmb_z, cmb_z_step;
6848
4/4
✓ Branch 0 taken 92789 times.
✓ Branch 1 taken 232344621 times.
✓ Branch 2 taken 88819 times.
✓ Branch 3 taken 3970 times.
232437410 if(cmb.type == cCSWITCHBLOCK && (cmb.usrflags & cflag9))
6849 {
6850 3970 cmb_z = zslongToFix(cmb.attributes[2]);
6851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3970 times.
3970 cmb_z_step = zslongToFix(zc_max(0,cmb.attributes[3]));
6852 3970 }
6853
2/2
✓ Branch 0 taken 1983 times.
✓ Branch 1 taken 232431457 times.
232433440 else if(cmb.genflags & cflag3)
6854 {
6855 1983 cmb_z = cmb.z_height;
6856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1983 times.
1983 cmb_z_step = zc_max(0_zf,cmb.z_step_height);
6857 1983 }
6858 232431457 else return false;
6859
6860
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 5953 times.
✓ Branch 2 taken 4804 times.
✓ Branch 3 taken 1149 times.
5953 return (standing_z_state < 0 || (cmb_z>0 && (cmb_z - cmb_z_step) <= standing_z_state));
6861 232437410 }
6862 56117558 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt)
6863 {
6864 56117558 return _walkflag(zx,zy,cnt,0_zf);
6865 }
6866
6867 132920561 bool _walkflag_new(const mapscr* s0, const mapscr* s1, const mapscr* s2, zfix_round zx, zfix_round zy, zfix const& standing_z_state, bool is_temp_screens)
6868 {
6869 132920561 int x = zx.getRound(), y = zy.getRound();
6870 132920561 int pos = COMBOPOS(x % 256, y % 176);
6871 132920561 const newcombo& c = combobuf[s0->data[pos]];
6872 132920561 const newcombo& c1 = combobuf[s1->data[pos]];
6873 132920561 const newcombo& c2 = combobuf[s2->data[pos]];
6874
4/4
✓ Branch 0 taken 130925120 times.
✓ Branch 1 taken 1995441 times.
✓ Branch 2 taken 130915660 times.
✓ Branch 3 taken 9460 times.
266043410 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6875
4/4
✓ Branch 0 taken 101153 times.
✓ Branch 1 taken 131016795 times.
✓ Branch 2 taken 2101809 times.
✓ Branch 3 taken 4245 times.
132920561 (iswater_type(c2.type))) && DRIEDLAKE);
6876 133122849 int32_t b=1;
6877
2/2
✓ Branch 0 taken 65628846 times.
✓ Branch 1 taken 67494003 times.
133122849 if(x&8) b<<=2;
6878
2/2
✓ Branch 0 taken 62187457 times.
✓ Branch 1 taken 70935392 times.
133122849 if(y&8) b<<=1;
6879
6880 133122849 int32_t cwalkflag = c.walk;
6881
4/4
✓ Branch 0 taken 133021705 times.
✓ Branch 1 taken 101144 times.
✓ Branch 2 taken 133021541 times.
✓ Branch 3 taken 164 times.
133122849 if(is_temp_screens && standing_on_z(c,standing_z_state)) cwalkflag &= (c.walk>>4)^0xF;
6882
8/10
✓ Branch 0 taken 50572 times.
✓ Branch 1 taken 133072113 times.
✓ Branch 2 taken 2096585 times.
✓ Branch 3 taken 2046013 times.
✓ Branch 4 taken 2096585 times.
✓ Branch 5 taken 133021541 times.
✓ Branch 6 taken 2096585 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2096585 times.
✗ Branch 9 not taken.
133122685 else if ((c.type == cBRIDGE && get_qr(qr_OLD_BRIDGE_COMBOS)) || (iswater_type(c.type) && ((c.walk>>4)&b) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6883
2/2
✓ Branch 0 taken 63476780 times.
✓ Branch 1 taken 69544925 times.
133021705 if (s1 != s0)
6884 {
6885
3/4
✓ Branch 0 taken 69544925 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69544307 times.
✓ Branch 3 taken 618 times.
69544925 if(is_temp_screens && standing_on_z(c1,standing_z_state)) cwalkflag &= (c1.walk>>4)^0xF;
6886
4/10
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69532578 times.
✓ Branch 2 taken 11729 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 11729 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
69544307 else if ((iswater_type(c1.type) && ((c1.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_1) && !((c1.usrflags&cflag3) || (c1.usrflags&cflag4)))) cwalkflag &= c1.walk;
6887
2/2
✓ Branch 0 taken 62906 times.
✓ Branch 1 taken 69481401 times.
69544307 else if (c1.type == cBRIDGE)
6888 {
6889
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62906 times.
62906 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6890 {
6891 62906 int efflag = (c1.walk & 0xF0)>>4;
6892 62906 int newsolid = (c1.walk & 0xF);
6893 62906 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6894 62906 }
6895 else cwalkflag &= c1.walk;
6896 62906 }
6897
3/8
✓ Branch 0 taken 11729 times.
✓ Branch 1 taken 69469672 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11729 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
69481401 else if ((iswater_type(c1.type) && get_qr(qr_WATER_ON_LAYER_1) && ((c1.usrflags&cflag3) || (c1.usrflags&cflag4)) && ((c1.walk>>4)&b))) cwalkflag = 0;
6898 69481401 else cwalkflag |= c1.walk;
6899 69544925 }
6900
2/2
✓ Branch 0 taken 103150925 times.
✓ Branch 1 taken 29870780 times.
133021705 if (s2 != s0)
6901 {
6902
2/4
✓ Branch 0 taken 29870780 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29870780 times.
✗ Branch 3 not taken.
29870780 if(is_temp_screens && standing_on_z(c2,standing_z_state)) cwalkflag &= (c2.walk>>4)^0xF;
6903
4/10
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29868626 times.
✓ Branch 2 taken 2154 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2154 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
29870780 else if ((iswater_type(c2.type) && ((c2.walk>>4)&b) && get_qr(qr_WATER_ON_LAYER_2) && !((c2.usrflags&cflag3) || (c2.usrflags&cflag4)))) cwalkflag &= c2.walk;
6904
2/2
✓ Branch 0 taken 4447 times.
✓ Branch 1 taken 29866333 times.
29870780 else if (c2.type == cBRIDGE)
6905 {
6906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4447 times.
4447 if (!get_qr(qr_OLD_BRIDGE_COMBOS))
6907 {
6908 4447 int efflag = (c2.walk & 0xF0)>>4;
6909 4447 int newsolid = (c2.walk & 0xF);
6910 4447 cwalkflag = ((newsolid | cwalkflag) & (~efflag)) | (newsolid & efflag);
6911 4447 }
6912 else cwalkflag &= c2.walk;
6913 4447 }
6914
3/8
✓ Branch 0 taken 2154 times.
✓ Branch 1 taken 29864179 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2154 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
29866333 else if ((iswater_type(c2.type) && get_qr(qr_WATER_ON_LAYER_2) && ((c2.usrflags&cflag3) || (c2.usrflags&cflag4))) && ((c2.walk>>4)&b)) cwalkflag = 0;
6915 29866333 else cwalkflag |= c2.walk;
6916 29870780 }
6917
6918
4/4
✓ Branch 0 taken 29568194 times.
✓ Branch 1 taken 103453511 times.
✓ Branch 2 taken 948 times.
✓ Branch 3 taken 29567246 times.
133021705 if((cwalkflag&b) && !dried)
6919 29567246 return true;
6920
6921
3/4
✓ Branch 0 taken 103454459 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103438048 times.
✓ Branch 3 taken 16411 times.
103454459 if (is_temp_screens && collide_object(zx, zy, 0.0001_zf, 0.0001_zf)) return true;
6922
6923 103438048 return false;
6924 133021705 }
6925
6926 // Returns true if the combo at viewport position x,y is solid. Looks at a combo's quadrant walkablity flags.
6927 133021705 static bool _walkflag_new(zfix_round zx, zfix_round zy, zfix const& standing_z_state)
6928 {
6929 133021705 int x = zx.getRound(), y = zy.getRound();
6930 133021705 mapscr* s0 = get_scr_for_world_xy_layer(x, y, 0);
6931 133021705 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6932 133021705 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6933
2/2
✓ Branch 0 taken 63476780 times.
✓ Branch 1 taken 69544925 times.
133021705 if (!s1->valid) s1 = s0;
6934
2/2
✓ Branch 0 taken 103150925 times.
✓ Branch 1 taken 29870780 times.
133021705 if (!s2->valid) s2 = s0;
6935 133021705 return _walkflag_new(s0, s1, s2, zx, zy, standing_z_state, true);
6936 }
6937
6938 128587954 bool _walkflag(zfix_round x,zfix_round y,int32_t cnt,zfix const& standing_z_state)
6939 {
6940 128587954 int max_x = world_w;
6941 128587954 int max_y = world_h;
6942
2/2
✓ Branch 0 taken 68545217 times.
✓ Branch 1 taken 60042737 times.
128587954 if (!get_qr(qr_LTTPWALK))
6943 {
6944 60042737 max_x -= 7;
6945 60042737 max_y -= 7;
6946 60042737 }
6947
4/4
✓ Branch 0 taken 128317122 times.
✓ Branch 1 taken 270832 times.
✓ Branch 2 taken 83268 times.
✓ Branch 3 taken 128233854 times.
128587954 if (x < 0 || y < 0) return false;
6948
2/2
✓ Branch 0 taken 322356 times.
✓ Branch 1 taken 127911498 times.
128233854 if (x >= max_x) return false;
6949
3/4
✓ Branch 0 taken 539663 times.
✓ Branch 1 taken 127371835 times.
✓ Branch 2 taken 539663 times.
✗ Branch 3 not taken.
127911498 if (x >= max_x - 8 && cnt == 2) return false;
6950
2/2
✓ Branch 0 taken 127362274 times.
✓ Branch 1 taken 549224 times.
127911498 if (y >= max_y) return false;
6951
6952
4/4
✓ Branch 0 taken 29465504 times.
✓ Branch 1 taken 97896770 times.
✓ Branch 2 taken 92237339 times.
✓ Branch 3 taken 5659431 times.
127362274 return _walkflag_new(x, y, standing_z_state) || (cnt != 1 && _walkflag_new(x + 8, y, standing_z_state));
6953 128587954 }
6954
6955 99143870 static bool effectflag(int32_t x, int32_t y, int32_t layer)
6956 {
6957 99143870 mapscr* s0 = get_scr_for_world_xy(x, y);
6958 99143870 mapscr* s1 = get_scr_for_world_xy_layer(x, y, 1);
6959 99143870 mapscr* s2 = get_scr_for_world_xy_layer(x, y, 2);
6960
2/2
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629348 times.
99143870 if (!s1->valid) s1 = s0;
6961
2/2
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491083 times.
99143870 if (!s2->valid) s2 = s0;
6962
6963 99143870 int pos = COMBOPOS(x % 256, y % 176);
6964 99143870 const newcombo& c = combobuf[s0->data[pos]];
6965 99143870 const newcombo& c1 = combobuf[s1->data[pos]];
6966 99143870 const newcombo& c2 = combobuf[s2->data[pos]];
6967
4/4
✓ Branch 0 taken 98216592 times.
✓ Branch 1 taken 927278 times.
✓ Branch 2 taken 98215226 times.
✓ Branch 3 taken 1366 times.
198287740 bool dried = (((iswater_type(c.type)) || (iswater_type(c1.type)) ||
6968
3/4
✗ Branch 0 not taken.
✓ Branch 1 taken 98215226 times.
✓ Branch 2 taken 926808 times.
✓ Branch 3 taken 1836 times.
99143870 (iswater_type(c2.type))) && DRIEDLAKE);
6969 99143870 int32_t b=1;
6970
2/2
✓ Branch 0 taken 49874789 times.
✓ Branch 1 taken 49269081 times.
99143870 if(x&8) b<<=2;
6971
2/2
✓ Branch 0 taken 41816616 times.
✓ Branch 1 taken 57327254 times.
99143870 if(y&8) b<<=1;
6972
6973 99143870 int32_t cwalkflag = (c.walk>>4);
6974
2/2
✓ Branch 0 taken 76350269 times.
✓ Branch 1 taken 22793601 times.
99143870 if (layer == 0) cwalkflag = (c1.walk>>4);
6975
2/2
✓ Branch 0 taken 76351467 times.
✓ Branch 1 taken 22792403 times.
99143870 if (layer == 1) cwalkflag = (c2.walk>>4);
6976 //if (c.type == cBRIDGE || (iswater_type(c.type) && ((c.usrflags&cflag3) || (c.usrflags&cflag4)))) cwalkflag = 0;
6977
4/4
✓ Branch 0 taken 51514522 times.
✓ Branch 1 taken 47629348 times.
✓ Branch 2 taken 22464483 times.
✓ Branch 3 taken 29050039 times.
99143870 if (s1 != s0 && layer < 0)
6978 {
6979
2/2
✓ Branch 0 taken 22451077 times.
✓ Branch 1 taken 13406 times.
22464483 if (c1.type == cBRIDGE) cwalkflag &= (~(c1.walk>>4));
6980 22464483 }
6981
4/4
✓ Branch 0 taken 17652787 times.
✓ Branch 1 taken 81491083 times.
✓ Branch 2 taken 13091910 times.
✓ Branch 3 taken 4560877 times.
99143870 if (s2 != s0 && layer < 1)
6982 {
6983
2/2
✓ Branch 0 taken 13086050 times.
✓ Branch 1 taken 5860 times.
13091910 if (c2.type == cBRIDGE) cwalkflag &= (~(c2.walk>>4));
6984 13091910 }
6985
6986
2/2
✓ Branch 0 taken 98984616 times.
✓ Branch 1 taken 159254 times.
99143870 return (cwalkflag&b) ? !dried : false;
6987 }
6988
6989 99518754 bool _effectflag(int32_t x,int32_t y,int32_t cnt, int32_t layer, bool notLink)
6990 {
6991 DCHECK(cnt == 0 || cnt == 1);
6992 99518754 int max_x = world_w;
6993 99518754 int max_y = world_h;
6994
3/4
✓ Branch 0 taken 45833723 times.
✓ Branch 1 taken 53685031 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 45833723 times.
99518754 if (!get_qr(qr_LTTPWALK) && !notLink)
6995 {
6996 45833723 max_x -= 7;
6997 45833723 max_y -= 7;
6998 45833723 }
6999
4/4
✓ Branch 0 taken 99518001 times.
✓ Branch 1 taken 753 times.
✓ Branch 2 taken 204 times.
✓ Branch 3 taken 99517797 times.
99518754 if (x < 0 || y < 0) return false;
7000
2/2
✓ Branch 0 taken 818 times.
✓ Branch 1 taken 99516979 times.
99517797 if (x >= max_x) return false;
7001
3/4
✓ Branch 0 taken 521780 times.
✓ Branch 1 taken 98995199 times.
✓ Branch 2 taken 521780 times.
✗ Branch 3 not taken.
99516979 if (x >= max_x - 8 && cnt == 2) return false;
7002
2/2
✓ Branch 0 taken 373109 times.
✓ Branch 1 taken 99143870 times.
99516979 if (y >= max_y) return false;
7003
7004
3/4
✓ Branch 0 taken 98983826 times.
✓ Branch 1 taken 160044 times.
✓ Branch 2 taken 160044 times.
✗ Branch 3 not taken.
99143870 return effectflag(x, y, layer) || (cnt == 2 && effectflag(x + 8, y, layer));
7005 99518754 }
7006
7007 // used by mapdata->isSolid(x,y) in ZScript
7008 bool _walkflag(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7009 {
7010 int x = zx.getRound(), y = zy.getRound();
7011 {
7012 int max_x = 256;
7013 int max_y = 176;
7014 if (!get_qr(qr_LTTPWALK))
7015 {
7016 max_x -= 7;
7017 max_y -= 7;
7018 }
7019 if (x < 0 || y < 0) return false;
7020 if (x >= max_x) return false;
7021 if (x >= max_x - 8 && cnt == 2) return false;
7022 if (y >= max_y) return false;
7023 }
7024
7025 const mapscr *s1, *s2;
7026
7027 if ( m->layermap[0] > 0 )
7028 {
7029 s1 = get_canonical_scr(m->layermap[0], m->layerscreen[0]);
7030 }
7031 else s1 = m;
7032
7033 if ( m->layermap[1] > 0 )
7034 {
7035 s2 = get_canonical_scr(m->layermap[1], m->layerscreen[1]);
7036 }
7037 else s2 = m;
7038
7039 zfix unused;
7040 return _walkflag_new(m, s1, s2, x, y, unused, false) || (cnt != 1 && _walkflag_new(m, s1, s2, x + 8, y, unused, false));
7041 }
7042
7043 bool _walkflag_layer(zfix_round x, zfix_round y, int32_t layer, int32_t cnt)
7044 {
7045 DCHECK_LAYER_NEG1_INDEX(layer);
7046 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7047 if (!m->is_valid()) return false;
7048 return _walkflag_layer(x, y, cnt, m);
7049 }
7050
7051 static bool _walkflag_layer_new(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m, int max_x, int max_y)
7052 {
7053 int x = zx.getRound(), y = zy.getRound();
7054
7055 if (!get_qr(qr_LTTPWALK))
7056 {
7057 max_x -= 7;
7058 max_y -= 7;
7059 }
7060 if (x < 0 || y < 0) return false;
7061 if (x >= max_x) return false;
7062 if (x >= max_x - 8 && cnt == 2) return false;
7063 if (y >= max_y) return false;
7064
7065 if(!m) return true;
7066
7067 int pos = COMBOPOS(x%256, y%176);
7068 const newcombo* c = &combobuf[m->data[pos]];
7069 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7070 int32_t b=1;
7071
7072 if(x&8) b<<=2;
7073
7074 if(y&8) b<<=1;
7075
7076 if((c->walk&b) && !dried)
7077 return true;
7078
7079 if(cnt==1) return false;
7080
7081 ++pos;
7082
7083 if(!(x&8))
7084 b<<=2;
7085 else
7086 {
7087 c = &combobuf[m->data[pos]];
7088 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7089 b=1;
7090
7091 if(y&8) b<<=1;
7092 }
7093
7094 return (c->walk&b) ? !dried : false;
7095 }
7096
7097 //Only check the given mapscr*, not its layer 1&2
7098 bool _walkflag_layer(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7099 {
7100 return _walkflag_layer_new(zx, zy, cnt, m, world_w, world_h);
7101 }
7102
7103 bool _walkflag_layer_scrolling(zfix_round zx,zfix_round zy,int32_t cnt, mapscr* m)
7104 {
7105 return _walkflag_layer_new(zx, zy, cnt, m, scrolling_region.width, scrolling_region.height);
7106 }
7107
7108 313446 bool _effectflag_layer(int32_t x, int32_t y, int32_t layer, int32_t cnt, bool notLink)
7109 {
7110 DCHECK_LAYER_NEG1_INDEX(layer);
7111 313446 mapscr* m = get_scr_for_world_xy_layer(x, y, layer + 1);
7112
2/2
✓ Branch 0 taken 1762 times.
✓ Branch 1 taken 311684 times.
313446 if (!m->is_valid()) return false;
7113 311684 return _effectflag_layer(x, y, cnt, m, notLink);
7114 313446 }
7115
7116 377717 bool _effectflag_layer(int32_t x,int32_t y,int32_t cnt, mapscr* m, bool notLink)
7117 {
7118 377717 int max_x = world_w;
7119 377717 int max_y = world_h;
7120
3/4
✓ Branch 0 taken 50002 times.
✓ Branch 1 taken 327715 times.
✓ Branch 2 taken 50002 times.
✗ Branch 3 not taken.
377717 if (!get_qr(qr_LTTPWALK) && !notLink)
7121 {
7122 max_x -= 7;
7123 max_y -= 7;
7124 }
7125
2/4
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 377717 times.
377717 if (x < 0 || y < 0) return false;
7126
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (x >= max_x) return false;
7127
3/4
✓ Branch 0 taken 1209 times.
✓ Branch 1 taken 376508 times.
✓ Branch 2 taken 1209 times.
✗ Branch 3 not taken.
377717 if (x >= max_x - 8 && cnt == 2) return false;
7128
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 377717 times.
377717 if (y >= max_y) return false;
7129
7130
1/2
✓ Branch 0 taken 377717 times.
✗ Branch 1 not taken.
377717 if (!m) return true;
7131
7132 377717 int pos = COMBOPOS(x%256, y%176);
7133 377717 const newcombo* c = &combobuf[m->data[pos]];
7134
3/4
✓ Branch 0 taken 377336 times.
✓ Branch 1 taken 381 times.
✓ Branch 2 taken 381 times.
✗ Branch 3 not taken.
378098 bool dried = ((iswater_type(c->type)) && DRIEDLAKE);
7135 377717 int32_t b=1;
7136
7137
2/2
✓ Branch 0 taken 205340 times.
✓ Branch 1 taken 172377 times.
377717 if(x&8) b<<=2;
7138
7139
2/2
✓ Branch 0 taken 157087 times.
✓ Branch 1 taken 220630 times.
377717 if(y&8) b<<=1;
7140
7141
3/4
✓ Branch 0 taken 308723 times.
✓ Branch 1 taken 68994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 308723 times.
377717 if(((c->walk>>4)&b) && !dried)
7142 308723 return true;
7143
7144
1/2
✓ Branch 0 taken 68994 times.
✗ Branch 1 not taken.
68994 if(cnt==1) return false;
7145
7146 ++pos;
7147
7148 if(!(x&8))
7149 b<<=2;
7150 else
7151 {
7152 c = &combobuf[m->data[pos]];
7153 dried = ((iswater_type(c->type)) && DRIEDLAKE);
7154 b=1;
7155
7156 if(y&8) b<<=1;
7157 }
7158
7159 return ((c->walk>>4)&b) ? !dried : false;
7160 377717 }
7161
7162 812605 bool water_walkflag(int32_t x, int32_t y, int32_t cnt)
7163 {
7164 812605 int max_x = world_w;
7165 812605 int max_y = world_h;
7166
2/2
✓ Branch 0 taken 117367 times.
✓ Branch 1 taken 695238 times.
812605 if (!get_qr(qr_LTTPWALK))
7167 {
7168 695238 max_x -= 7;
7169 695238 max_y -= 7;
7170 695238 }
7171
2/4
✓ Branch 0 taken 812605 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 812605 times.
812605 if (x < 0 || y < 0) return false;
7172
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (x >= max_x) return false;
7173
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
812605 if (x >= max_x - 8 && cnt == 2) return false;
7174
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if (y >= max_y) return false;
7175
7176
3/4
✓ Branch 0 taken 16825 times.
✓ Branch 1 taken 795780 times.
✓ Branch 2 taken 795780 times.
✗ Branch 3 not taken.
812605 return water_walkflag(x, y) || (cnt != 1 && water_walkflag(x + 8, y));
7177 812605 }
7178
7179 812605 bool water_walkflag(int32_t x, int32_t y)
7180 {
7181 812605 const newcombo& c = combobuf[MAPCOMBO2(-1, x, y)];
7182 812605 const newcombo& c1 = combobuf[MAPCOMBO2(0, x, y)];
7183 812605 const newcombo& c2 = combobuf[MAPCOMBO2(1, x, y)];
7184
7185 812605 int32_t b=1;
7186
2/2
✓ Branch 0 taken 414677 times.
✓ Branch 1 taken 397928 times.
812605 if(x&8) b<<=2;
7187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 812605 times.
812605 if(y&8) b<<=1;
7188
7189
2/2
✓ Branch 0 taken 26377 times.
✓ Branch 1 taken 786228 times.
812605 if(get_qr(qr_NO_SOLID_SWIM))
7190 {
7191
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 26245 times.
26377 if(c.walk&b)
7192 132 return true;
7193
7194
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 25953 times.
26245 if(c1.walk&b)
7195 292 return true;
7196
7197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25953 times.
25953 if(c2.walk&b)
7198 return true;
7199 25953 }
7200 else
7201 {
7202
4/4
✓ Branch 0 taken 36133 times.
✓ Branch 1 taken 750095 times.
✓ Branch 2 taken 19762 times.
✓ Branch 3 taken 16371 times.
786228 if((c.walk&b) && !iswater_type(c.type))
7203 16371 return true;
7204
7205
3/4
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 769840 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
769857 if((c1.walk&b) && !iswater_type(c1.type))
7206 17 return true;
7207
7208
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 769827 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
769840 if((c2.walk&b) && !iswater_type(c2.type))
7209 13 return true;
7210 }
7211
7212 795780 return false;
7213 812605 }
7214
7215 564116 bool hit_walkflag(int32_t x,int32_t y,int32_t cnt)
7216 {
7217
2/2
✓ Branch 0 taken 90999 times.
✓ Branch 1 taken 473117 times.
564116 if(dlevel)
7218
8/8
✓ Branch 0 taken 471712 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 468517 times.
✓ Branch 3 taken 3195 times.
✓ Branch 4 taken 466857 times.
✓ Branch 5 taken 1660 times.
✓ Branch 6 taken 4199 times.
✓ Branch 7 taken 462658 times.
473117 if(x<32 || y<40 || (x+(cnt-1)*8)>=world_w-32 || y>=world_h-32)
7219 10459 return true;
7220
7221
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 553655 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
553657 if(blockpath && y<((get_qr(qr_LTTPCOLLISION))?80:88))
7222 return true;
7223
7224
8/8
✓ Branch 0 taken 553388 times.
✓ Branch 1 taken 269 times.
✓ Branch 2 taken 553155 times.
✓ Branch 3 taken 233 times.
✓ Branch 4 taken 552946 times.
✓ Branch 5 taken 209 times.
✓ Branch 6 taken 346 times.
✓ Branch 7 taken 552600 times.
553657 if(x<16 || y<16 || (x+(cnt-1)*8)>=world_w-16 || y>=world_h-16)
7225 1057 return true;
7226
7227 // for(int32_t i=0; i<4; i++)
7228
4/4
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 551759 times.
✓ Branch 2 taken 36 times.
✓ Branch 3 taken 805 times.
552600 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7229 36 return true;
7230
7231
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 552564 times.
552564 if (collide_object(x, y,cnt*8, 1))
7232 return true;
7233
7234 552564 return _walkflag(x,y,cnt);
7235 564116 }
7236
7237 12110 bool solpush_walkflag(int32_t x, int32_t y, int32_t cnt, solid_object const* ign)
7238 {
7239 // 16 pixel buffer to account for slopes that are on bordering screens.
7240
4/8
✓ Branch 0 taken 12110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12110 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 12110 times.
12110 if(x<0 || y<0 || x>=world_w+16 || y>=world_h+16)
7241 return true;
7242
7243 // for(int32_t i=0; i<4; i++)
7244
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12110 if(mblock2.clk && mblock2.hit(x,y,0,cnt*8,1,16))
7245 return true;
7246
7247
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12110 times.
12110 if (collide_object(x, y,cnt*8, 1, ign))
7248 return true;
7249
7250 12110 return _walkflag(x,y,cnt);
7251 12110 }
7252
7253 37837 void map_bkgsfx(bool on)
7254 {
7255
2/2
✓ Branch 0 taken 37816 times.
✓ Branch 1 taken 21 times.
37837 if(on)
7256 {
7257 37816 cont_sfx(hero_scr->oceansfx);
7258
7259
4/4
✓ Branch 0 taken 369 times.
✓ Branch 1 taken 37447 times.
✓ Branch 2 taken 315 times.
✓ Branch 3 taken 54 times.
37816 if(hero_scr->bosssfx && !(game->lvlitems[dlevel]&liBOSS))
7260 315 cont_sfx(hero_scr->bosssfx);
7261 37816 }
7262 else
7263 {
7264 21 adjust_sfx(hero_scr->oceansfx,128,false);
7265 21 adjust_sfx(hero_scr->bosssfx,128,false);
7266
7267
2/2
✓ Branch 0 taken 114 times.
✓ Branch 1 taken 21 times.
135 for(int32_t i=0; i<guys.Count(); i++)
7268 {
7269
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 84 times.
114 if(((enemy*)guys.spr(i))->bgsfx)
7270 84 stop_sfx(((enemy*)guys.spr(i))->bgsfx);
7271 114 }
7272 }
7273 37837 }
7274
7275 239 void toggle_switches(dword flags, bool entry)
7276 {
7277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239 times.
239 if(!flags) return; //No flags to toggle
7278
7279 478 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7280 239 toggle_switches(flags, entry, create_screen_handles(scr));
7281 239 });
7282 239 }
7283 54044 void toggle_switches(dword flags, bool entry, const screen_handles_t& screen_handles)
7284 {
7285
2/2
✓ Branch 0 taken 737 times.
✓ Branch 1 taken 53307 times.
54044 if(!flags) return; //No flags to toggle
7286
7287 737 mapscr* m = screen_handles[0].base_scr;
7288 737 int screen = m->screen;
7289 737 bool is_active_screen = is_in_current_region(m);
7290
7291 305041 for_every_rpos_in_screen(screen_handles, [&](const rpos_handle_t& rpos_handle) {
7292 304304 byte togglegrid[176] = {0};
7293 304304 mapscr* scr = rpos_handle.scr;
7294 304304 int lyr = rpos_handle.layer;
7295 304304 int pos = rpos_handle.pos;
7296 304304 newcombo const& cmb = combobuf[scr->data[pos]];
7297
2/2
✓ Branch 0 taken 39424 times.
✓ Branch 1 taken 264880 times.
304304 if(is_active_screen)
7298
1/2
✓ Branch 0 taken 264880 times.
✗ Branch 1 not taken.
367773 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7299
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 102893 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
102893 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7300 }, ctrigSWITCHSTATE);
7301
3/4
✓ Branch 0 taken 303641 times.
✓ Branch 1 taken 663 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2760 times.
304304 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32
7302
2/2
✓ Branch 0 taken 2760 times.
✓ Branch 1 taken 301544 times.
304304 && !(cmb.usrflags & cflag11)) //global state
7303 {
7304
2/2
✓ Branch 0 taken 446 times.
✓ Branch 1 taken 2314 times.
2760 if(flags&(1<<cmb.attribytes[0]))
7305 {
7306 2314 set<int32_t> oldData;
7307 //Increment the combo/cset by the attributes
7308 2314 int32_t cmbofs = (cmb.attributes[0]/10000L);
7309 2314 int32_t csofs = (cmb.attributes[1]/10000L);
7310
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 oldData.insert(scr->data[pos]);
7311
1/2
✓ Branch 0 taken 2314 times.
✗ Branch 1 not taken.
2314 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7312 2314 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7313
4/4
✓ Branch 0 taken 1435 times.
✓ Branch 1 taken 879 times.
✓ Branch 2 taken 1197 times.
✓ Branch 3 taken 238 times.
2314 if(entry && (cmb.usrflags&cflag8))
7314 {
7315 238 newcombo const* tmp = &combobuf[scr->data[pos]];
7316
2/4
✓ Branch 0 taken 238 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 238 times.
✗ Branch 3 not taken.
238 while(tmp->can_cycle())
7317 {
7318 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7319 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7320 if(oldData.find(cid) != oldData.end())
7321 break;
7322
7323 scr->data[pos] = cid;
7324 if(!(tmp->animflags & AF_CYCLENOCSET))
7325 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7326 oldData.insert(cid);
7327 tmp = &combobuf[cid];
7328 }
7329 238 }
7330 2314 int32_t cmbid = scr->data[pos];
7331
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2273 times.
2314 if(combobuf[cmbid].animflags & AF_CYCLE)
7332 {
7333 41 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7334 41 combobuf[cmbid].cur_frame=0;
7335 41 combobuf[cmbid].aclk = 0;
7336
1/2
✓ Branch 0 taken 41 times.
✗ Branch 1 not taken.
41 combo_caches::drawing.refresh(cmbid);
7337 41 }
7338 2314 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7339
2/2
✓ Branch 0 taken 511 times.
✓ Branch 1 taken 1803 times.
2314 if(cmb.type == cCSWITCH) return; //Switches don't toggle other layers
7340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2147 times.
2147 for(int32_t lyr2 = 0; lyr2 < 7; ++lyr2) //Toggle same pos on other layers, if flag set
7341 {
7342
2/2
✓ Branch 0 taken 1671 times.
✓ Branch 1 taken 476 times.
2147 if(lyr==lyr2) return;
7343
2/2
✓ Branch 0 taken 132 times.
✓ Branch 1 taken 344 times.
476 if(!(cmb.usrflags&(1<<lyr2))) return;
7344
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(togglegrid[pos]&(1<<lyr2)) return;
7345
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
344 mapscr* scr_2 = (lyr2 ? get_scr_layer(screen, lyr2) : m);
7346
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 if(!scr_2->data[pos]) //Don't increment empty space
7347 return;
7348 344 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7349
1/6
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
344 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK) && !(cmb.usrflags & cflag11)
7350 && cmb_2.attribytes[0] < 32 && (flags&(1<<cmb_2.attribytes[0])))
7351 return; //This is a switch/block that will be hit later in the loop!
7352 344 set<int32_t> oldData2;
7353 //Increment the combo/cset by the original cmb's attributes
7354
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 oldData2.insert(scr_2->data[pos]);
7355
1/2
✓ Branch 0 taken 344 times.
✗ Branch 1 not taken.
344 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7356 344 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7357
3/4
✓ Branch 0 taken 50 times.
✓ Branch 1 taken 294 times.
✓ Branch 2 taken 50 times.
✗ Branch 3 not taken.
344 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7358 {
7359 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7360 while(tmp->can_cycle())
7361 {
7362 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7363 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7364 if(oldData2.find(cid) != oldData2.end())
7365 break;
7366
7367 scr_2->data[pos] = cid;
7368 if(!(tmp->animflags & AF_CYCLENOCSET))
7369 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7370 oldData2.insert(cid);
7371 tmp = &combobuf[cid];
7372 }
7373 }
7374 344 int32_t cmbid2 = scr_2->data[pos];
7375
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344 times.
344 if(combobuf[cmbid2].animflags & AF_CYCLE)
7376 {
7377 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7378 combobuf[cmbid2].cur_frame=0;
7379 combobuf[cmbid2].aclk = 0;
7380 combo_caches::drawing.refresh(cmbid2);
7381 }
7382 344 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7383 344 }
7384
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 2314 times.
✗ Branch 2 not taken.
2314 }
7385 446 }
7386 304304 });
7387
7388
3/4
✓ Branch 0 taken 519 times.
✓ Branch 1 taken 218 times.
✓ Branch 2 taken 519 times.
✗ Branch 3 not taken.
737 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7389 {
7390 newcombo const& cmb = combobuf[mblock2.bcombo];
7391 if(!(cmb.usrflags & cflag11) && (cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && cmb.attribytes[0] < 32)
7392 {
7393 if(flags&(1<<cmb.attribytes[0]))
7394 {
7395 //Increment the combo/cset by the attributes
7396 int32_t cmbofs = (cmb.attributes[0]/10000L);
7397 int32_t csofs = (cmb.attributes[1]/10000L);
7398 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7399 mblock2.cs = (mblock2.cs + csofs) & 15;
7400 int32_t cmbid = mblock2.bcombo;
7401 if(combobuf[cmbid].animflags & AF_CYCLE)
7402 {
7403 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7404 combobuf[cmbid].cur_frame=0;
7405 combobuf[cmbid].aclk = 0;
7406 combo_caches::drawing.refresh(cmbid);
7407 }
7408 }
7409 }
7410 }
7411
7412
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 513 times.
737 if (is_active_screen)
7413 {
7414 513 int screen_index_offset = get_region_screen_offset(m->screen);
7415 513 word c = m->numFFC();
7416
2/2
✓ Branch 0 taken 334 times.
✓ Branch 1 taken 513 times.
847 for (int q = 0; q < c; ++q)
7417 {
7418 334 auto ffc_handle = *m->getFFCHandle(q, screen_index_offset);
7419
1/2
✓ Branch 0 taken 334 times.
✗ Branch 1 not taken.
363 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7420
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 29 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
29 return trig.trigger_flags.get(TRIGFLAG_TRIGLEVELSTATE) && trig.trig_lstate < 32 && (flags&(1<<trig.trig_lstate));
7421 }, ctrigSWITCHSTATE);
7422 334 }
7423 513 }
7424 54044 }
7425
7426 1 void toggle_gswitches(int32_t state, bool entry)
7427 {
7428 2 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7429 1 toggle_gswitches(state, entry, create_screen_handles(scr));
7430 1 });
7431 1 }
7432 1 void toggle_gswitches(int32_t state, bool entry, const screen_handles_t& screen_handles)
7433 {
7434 1 bool states[256] = {false};
7435 1 states[state] = true;
7436 1 toggle_gswitches(states, entry, screen_handles);
7437 1 }
7438 15216334 void toggle_gswitches(bool* states, bool entry, const screen_handles_t& screen_handles)
7439 {
7440
1/2
✓ Branch 0 taken 15216334 times.
✗ Branch 1 not taken.
15216334 if(!states) return;
7441
7442 15216334 auto& combo_cache = combo_caches::gswitch;
7443 15216334 mapscr* base_scr = screen_handles[0].base_scr;
7444 15216334 int screen = base_scr->screen;
7445 15216334 bool is_active_screen = is_in_current_region(base_scr);
7446 15216334 byte togglegrid[176] = {0};
7447
2/2
✓ Branch 0 taken 15216334 times.
✓ Branch 1 taken 106514338 times.
121730672 for(int32_t lyr = 0; lyr <= 6; ++lyr)
7448 {
7449 106514338 mapscr* scr = screen_handles[lyr].scr;
7450
2/2
✓ Branch 0 taken 32314143 times.
✓ Branch 1 taken 74200195 times.
106514338 if (!scr)
7451 74200195 continue;
7452
7453
2/2
✓ Branch 0 taken 32314143 times.
✓ Branch 1 taken 5687289168 times.
5719603311 for(int32_t pos = 0; pos < 176; ++pos)
7454 {
7455 5687289168 int cid = scr->data[pos];
7456 5687289168 auto& mini_cmb = combo_cache.minis[cid];
7457
7458
2/2
✓ Branch 0 taken 93475360 times.
✓ Branch 1 taken 5593813808 times.
5687289168 if (is_active_screen)
7459 {
7460
2/2
✓ Branch 0 taken 5593811926 times.
✓ Branch 1 taken 1882 times.
5593813808 if (mini_cmb.trigger_global_state)
7461 {
7462 1882 auto rpos_handle = get_rpos_handle_for_screen(screen, lyr, pos);
7463
1/2
✓ Branch 0 taken 1882 times.
✗ Branch 1 not taken.
3764 trig_each_combo_trigger(rpos_handle, [&](combo_trigger const& trig){
7464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1882 times.
1882 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7465 }, ctrigSWITCHSTATE);
7466 1882 }
7467 5593813808 }
7468
7469
2/2
✓ Branch 0 taken 40395 times.
✓ Branch 1 taken 5687248773 times.
5687289168 if (!mini_cmb.has_global_state)
7470 5687248773 continue;
7471
7472 40395 newcombo const& cmb = combobuf[cid];
7473
2/4
✓ Branch 0 taken 40395 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 40395 times.
40395 if(cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK)
7474 {
7475 if(states[cmb.attribytes[0]])
7476 {
7477 set<int32_t> oldData;
7478 //Increment the combo/cset by the attributes
7479 int32_t cmbofs = (cmb.attributes[0]/10000L);
7480 int32_t csofs = (cmb.attributes[1]/10000L);
7481 oldData.insert(scr->data[pos]);
7482 scr->data[pos] = BOUND_COMBO(scr->data[pos] + cmbofs);
7483 scr->cset[pos] = (scr->cset[pos] + csofs) & 15;
7484 if(entry && (cmb.usrflags&cflag8))
7485 {
7486 newcombo const* tmp = &combobuf[scr->data[pos]];
7487 while(tmp->can_cycle())
7488 {
7489 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7490 auto cid = cycle_under ? scr->undercombo : tmp->nextcombo;
7491 if(oldData.find(cid) != oldData.end())
7492 break;
7493 scr->data[pos] = cid;
7494 if(!(tmp->animflags & AF_CYCLENOCSET))
7495 scr->cset[pos] = cycle_under ? scr->undercset : tmp->nextcset;
7496 oldData.insert(cid);
7497 tmp = &combobuf[cid];
7498 }
7499 }
7500 int32_t cmbid = scr->data[pos];
7501 if(combobuf[cmbid].animflags & AF_CYCLE)
7502 {
7503 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7504 combobuf[cmbid].cur_frame=0;
7505 combobuf[cmbid].aclk = 0;
7506 combo_caches::drawing.refresh(cmbid);
7507 }
7508 togglegrid[pos] |= (1<<lyr); //Mark this pos toggled for this layer
7509 if(cmb.type == cCSWITCH) continue; //Switches don't toggle other layers
7510 for(int32_t lyr2 = 0; lyr2 <= 6; ++lyr2) //Toggle same pos on other layers, if flag set
7511 {
7512 if(lyr==lyr2) continue;
7513 if(!(cmb.usrflags&(1<<lyr2))) continue;
7514 if(togglegrid[pos]&(1<<lyr2)) continue;
7515 mapscr* scr_2 = lyr2 == 0 ? base_scr : get_scr_layer_valid(screen, lyr2);
7516 if(!scr_2 || !scr_2->data[pos]) //Don't increment empty space
7517 continue;
7518 newcombo const& cmb_2 = combobuf[scr_2->data[pos]];
7519 if(lyr2 > lyr && (cmb_2.type == cCSWITCH || cmb_2.type == cCSWITCHBLOCK)
7520 && (cmb_2.usrflags & cflag11) && (states[cmb_2.attribytes[0]]))
7521 continue; //This is a switch/block that will be hit later in the loop!
7522 set<int32_t> oldData2;
7523 //Increment the combo/cset by the original cmb's attributes
7524 oldData2.insert(scr_2->data[pos]);
7525 scr_2->data[pos] = BOUND_COMBO(scr_2->data[pos] + cmbofs);
7526 scr_2->cset[pos] = (scr_2->cset[pos] + csofs) & 15;
7527 if(entry && (cmb.usrflags&cflag8)) //Skip cycling on screen entry
7528 {
7529 newcombo const* tmp = &combobuf[scr_2->data[pos]];
7530 while(tmp->can_cycle())
7531 {
7532 bool cycle_under = (tmp->animflags & AF_CYCLEUNDERCOMBO);
7533 auto cid = cycle_under ? scr_2->undercombo : tmp->nextcombo;
7534 if(oldData2.find(cid) != oldData2.end())
7535 break;
7536 scr_2->data[pos] = cid;
7537 if(!(tmp->animflags & AF_CYCLENOCSET))
7538 scr_2->cset[pos] = cycle_under ? scr_2->undercset : tmp->nextcset;
7539 oldData2.insert(cid);
7540 tmp = &combobuf[cid];
7541 }
7542 }
7543 int32_t cmbid2 = scr_2->data[pos];
7544 if(combobuf[cmbid2].animflags & AF_CYCLE)
7545 {
7546 combobuf[cmbid2].tile = combobuf[cmbid2].o_tile;
7547 combobuf[cmbid2].cur_frame=0;
7548 combobuf[cmbid2].aclk = 0;
7549 combo_caches::drawing.refresh(cmbid2);
7550 }
7551 togglegrid[pos] |= (1<<lyr2); //Mark this pos toggled for this layer
7552 }
7553 }
7554 }
7555 40395 }
7556 32314143 }
7557
7558
4/4
✓ Branch 0 taken 547048 times.
✓ Branch 1 taken 14669286 times.
✓ Branch 2 taken 542304 times.
✓ Branch 3 taken 4744 times.
15216334 if(get_qr(qr_SWITCHES_AFFECT_MOVINGBLOCKS) && mblock2.clk)
7559 {
7560 4744 newcombo const& cmb = combobuf[mblock2.bcombo];
7561
2/4
✓ Branch 0 taken 4744 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4744 times.
✗ Branch 3 not taken.
4744 if((cmb.type == cCSWITCH || cmb.type == cCSWITCHBLOCK) && (cmb.usrflags & cflag11))
7562 {
7563 if(states[cmb.attribytes[0]])
7564 {
7565 //Increment the combo/cset by the attributes
7566 int32_t cmbofs = (cmb.attributes[0]/10000L);
7567 int32_t csofs = (cmb.attributes[1]/10000L);
7568 mblock2.bcombo = BOUND_COMBO(mblock2.bcombo + cmbofs);
7569 mblock2.cs = (mblock2.cs + csofs) & 15;
7570 int32_t cmbid = mblock2.bcombo;
7571 if(combobuf[cmbid].animflags & AF_CYCLE)
7572 {
7573 combobuf[cmbid].tile = combobuf[cmbid].o_tile;
7574 combobuf[cmbid].cur_frame=0;
7575 combobuf[cmbid].aclk = 0;
7576 combo_caches::drawing.refresh(cmbid);
7577 }
7578 }
7579 }
7580 4744 }
7581
7582
2/2
✓ Branch 0 taken 413479 times.
✓ Branch 1 taken 14802855 times.
15216334 if(is_active_screen)
7583 {
7584 14802855 int screen_index_offset = get_region_screen_offset(screen);
7585 14802855 word c = base_scr->numFFC();
7586
2/2
✓ Branch 0 taken 441793087 times.
✓ Branch 1 taken 14802855 times.
456595942 for (int q = 0; q < c; ++q)
7587 {
7588 441793087 auto ffc_handle = *base_scr->getFFCHandle(q, screen_index_offset);
7589
1/2
✓ Branch 0 taken 441793087 times.
✗ Branch 1 not taken.
442021875 trig_each_combo_trigger(ffc_handle, [&](combo_trigger const& trig){
7590
1/2
✓ Branch 0 taken 228788 times.
✗ Branch 1 not taken.
228788 return trig.trigger_flags.get(TRIGFLAG_TRIGGLOBALSTATE) && states[trig.trig_gstate];
7591 }, ctrigSWITCHSTATE);
7592 441793087 }
7593 14802855 }
7594 15216334 }
7595 53805 void toggle_gswitches_load(const screen_handles_t& screen_handles)
7596 {
7597 bool states[256];
7598
2/2
✓ Branch 0 taken 13774080 times.
✓ Branch 1 taken 53805 times.
13827885 for(auto q = 0; q < 256; ++q)
7599 {
7600 13774080 states[q] = game->gswitch_timers[q] != 0;
7601 13774080 }
7602 53805 toggle_gswitches(states, true, screen_handles);
7603 53805 }
7604 14773160 void run_gswitch_timers()
7605 {
7606 14773160 bool states[256] = {false};
7607 14773160 auto& m = game->gswitch_timers.mut_inner();
7608
2/2
✓ Branch 0 taken 3777886720 times.
✓ Branch 1 taken 14773160 times.
3792659880 for(auto it = m.begin(); it != m.end();)
7609 {
7610
2/2
✓ Branch 0 taken 3777886120 times.
✓ Branch 1 taken 600 times.
3777886720 if(it->second > 0)
7611
2/2
✓ Branch 0 taken 599 times.
✓ Branch 1 taken 1 times.
600 if(!--it->second)
7612 {
7613 1 states[it->first] = true;
7614 1 it = m.erase(it);
7615 1 continue;
7616 }
7617 3777886719 ++it;
7618 }
7619 29935688 for_every_base_screen_in_region([&](mapscr* scr, unsigned int region_scr_x, unsigned int region_scr_y) {
7620 15162528 toggle_gswitches(states, false, create_screen_handles(scr));
7621 15162528 });
7622 14773160 }
7623 1116 void onload_gswitch_timers() //Reset all timers that were counting down, no trigger necessary
7624 {
7625
2/2
✓ Branch 0 taken 285696 times.
✓ Branch 1 taken 1116 times.
286812 for(auto q = 0; q < 256; ++q)
7626 {
7627
1/2
✓ Branch 0 taken 285696 times.
✗ Branch 1 not taken.
285696 if(game->gswitch_timers[q] > 0)
7628 game->gswitch_timers[q] = 0;
7629 285696 }
7630 1116 }
7631
7632 /**** View Map ****/
7633
7634 int32_t mapres = 0;
7635 int32_t view_map_show_mode = 3;
7636
7637 124544 bool displayOnMap(int32_t x, int32_t y)
7638 {
7639 124544 int32_t s = (y<<4) + x;
7640 124544 int mi = mapind(cur_map, s);
7641
2/2
✓ Branch 0 taken 67891 times.
✓ Branch 1 taken 56653 times.
124544 if (!(game->maps[mi]&mVISITED))
7642 67891 return false;
7643
7644 // Don't display if not part of DMap
7645
4/4
✓ Branch 0 taken 15628 times.
✓ Branch 1 taken 41025 times.
✓ Branch 2 taken 4655 times.
✓ Branch 3 taken 4311 times.
65619 if(((DMaps[cur_dmap].flags&dmfDMAPMAP) &&
7646
1/2
✓ Branch 0 taken 15628 times.
✗ Branch 1 not taken.
15628 (DMaps[cur_dmap].type != dmOVERW) &&
7647
2/2
✓ Branch 0 taken 12495 times.
✓ Branch 1 taken 3133 times.
15628 !(x >= DMaps[cur_dmap].xoff &&
7648
2/2
✓ Branch 0 taken 8966 times.
✓ Branch 1 taken 3529 times.
12495 x < DMaps[cur_dmap].xoff+8 &&
7649 8966 DMaps[cur_dmap].grid[y]&(128>>(x-DMaps[cur_dmap].xoff)))))
7650 10973 return false;
7651 else
7652 45680 return true;
7653 124544 }
7654
7655 973 void ViewMap()
7656 {
7657 973 ViewingMap = true;
7658
7659 973 BITMAP* mappic = NULL;
7660 static double scales[17] =
7661 {
7662 0.03125, 0.04419, 0.0625, 0.08839, 0.125, 0.177, 0.25, 0.3535,
7663 0.50, 0.707, 1.0, 1.414, 2.0, 2.828, 4.0, 5.657, 8.0
7664 };
7665
7666 // Cursor position for hero, in absolute map coordinates.
7667 973 int32_t lx = ((cur_screen & 15) << 8) + HeroX() + 8;
7668 973 int32_t ly = ((cur_screen >> 4) * 176) + HeroY() + 8;
7669
7670 int32_t px;
7671 int32_t py;
7672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 973 times.
973 if (is_in_scrolling_region())
7673 {
7674 // Center the player on the middle of the map view.
7675 px = (16*256/2 - lx) * 2;
7676 py = (8*176/2 - ly) * 2;
7677 }
7678 else
7679 {
7680 // Center the current screen on the middle of the map view.
7681 973 px = ((8-(cur_screen&15)) << 9) - 256;
7682 973 py = ((4-(cur_screen>>4)) * 352) - 176;
7683 }
7684
7685 973 int32_t sc = 6;
7686
7687 973 bool done=false, redraw=true;
7688
7689 973 mappic = create_bitmap_ex(8,(256*16)>>mapres,(176*8)>>mapres);
7690
7691
1/2
✓ Branch 0 taken 973 times.
✗ Branch 1 not taken.
973 if(!mappic)
7692 {
7693 enter_sys_pal();
7694 jwin_alert("View Map","Not enough memory.",NULL,NULL,"OK",NULL,13,27,get_zc_font(font_lfont));
7695 exit_sys_pal();
7696 return;
7697 }
7698
7699 973 clear_to_color(mappic, WHITE);
7700
7701 973 auto prev_viewport = viewport;
7702 973 viewport.x = 0;
7703 973 viewport.y = 0;
7704
7705 // draw the map
7706 973 BITMAP* screen_bmp = create_bitmap_ex(8, 256, 176);
7707 973 combotile_add_x = 256;
7708 973 combotile_add_y = 0;
7709
2/2
✓ Branch 0 taken 7784 times.
✓ Branch 1 taken 973 times.
8757 for(int32_t y=0; y<8; y++)
7710 {
7711
2/2
✓ Branch 0 taken 124544 times.
✓ Branch 1 taken 7784 times.
132328 for(int32_t x=0; x<16; x++)
7712 {
7713
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 78864 times.
124544 if (!displayOnMap(x, y))
7714 78864 continue;
7715
7716 45680 int screen = map_scr_xy_to_index(x, y);
7717 45680 auto scrs = loadscr2(screen);
7718 45680 mapscr* scr = &scrs[0];
7719
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if (!scr->is_valid())
7720 continue;
7721
7722 screen_handles_t screen_handles;
7723
2/2
✓ Branch 0 taken 45680 times.
✓ Branch 1 taken 319760 times.
365440 for (int i = 0; i <= 6; i++)
7724
3/4
✓ Branch 0 taken 319760 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 103790 times.
✓ Branch 3 taken 215970 times.
319760 screen_handles[i] = {scr, scrs[i].is_valid() ? &scrs[i] : nullptr, screen, i};
7725
7726 45680 int xx = 0;
7727 45680 int yy = -playing_field_offset;
7728
7729
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 45660 times.
45680 if(XOR(scr->flags7&fLAYER2BG, DMaps[cur_dmap].flags&dmfLAYER2BG))
7730 {
7731
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7732
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 do_ffc_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7733 20 }
7734
7735
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 45505 times.
45680 if(XOR(scr->flags7&fLAYER3BG, DMaps[cur_dmap].flags&dmfLAYER3BG))
7736 {
7737
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7738
1/2
✓ Branch 0 taken 175 times.
✗ Branch 1 not taken.
175 do_ffc_layer(screen_bmp, -3, screen_handles[0], xx, yy);
7739 175 }
7740
7741
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
✗ Branch 3 not taken.
45680 if(lenscheck(scr,0)) putscr(scr, screen_bmp, 0, 0);
7742
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 0, screen_handles[0], xx, yy);
7743
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[1], xx, yy);
7744
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 1, screen_handles[0], xx, yy);
7745
7746
2/2
✓ Branch 0 taken 45660 times.
✓ Branch 1 taken 20 times.
45680 if(!XOR((scr->flags7&fLAYER2BG), DMaps[cur_dmap].flags&dmfLAYER2BG))
7747 {
7748
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_layer(screen_bmp, 0, screen_handles[2], xx, yy);
7749
1/2
✓ Branch 0 taken 45660 times.
✗ Branch 1 not taken.
45660 do_ffc_layer(screen_bmp, 2, screen_handles[0], xx, yy);
7750 45660 }
7751
7752
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 putscrdoors(scr, screen_bmp, xx, yy);
7753
2/2
✓ Branch 0 taken 41678 times.
✓ Branch 1 taken 4002 times.
45680 if (get_qr(qr_PUSHBLOCK_SPRITE_LAYER))
7754 {
7755
1/2
✓ Branch 0 taken 41678 times.
✗ Branch 1 not taken.
41678 do_layer(screen_bmp, -2, screen_handles[0], xx, yy);
7756
2/2
✓ Branch 0 taken 1782 times.
✓ Branch 1 taken 39896 times.
41678 if(get_qr(qr_PUSHBLOCK_LAYER_1_2))
7757 {
7758
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[1], xx, yy);
7759
1/2
✓ Branch 0 taken 1782 times.
✗ Branch 1 not taken.
1782 do_layer(screen_bmp,-2, screen_handles[2], xx, yy);
7760 1782 }
7761 41678 }
7762
7763
2/2
✓ Branch 0 taken 45505 times.
✓ Branch 1 taken 175 times.
45680 if(!XOR((scr->flags7&fLAYER3BG), DMaps[cur_dmap].flags&dmfLAYER3BG))
7764 {
7765
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_layer(screen_bmp, 0, screen_handles[3], xx, yy);
7766
1/2
✓ Branch 0 taken 45505 times.
✗ Branch 1 not taken.
45505 do_ffc_layer(screen_bmp, 3, screen_handles[0], xx, yy);
7767 45505 }
7768
7769
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[4], xx, yy);
7770
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 4, screen_handles[0], xx, yy);
7771
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7772
2/2
✓ Branch 0 taken 5784 times.
✓ Branch 1 taken 39896 times.
45680 if(get_qr(qr_OVERHEAD_COMBOS_L1_L2))
7773 {
7774
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[1], xx, yy);
7775
1/2
✓ Branch 0 taken 5784 times.
✗ Branch 1 not taken.
5784 do_layer(screen_bmp,-1, screen_handles[2], xx, yy);
7776 5784 }
7777
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[5], xx, yy);
7778
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 5, screen_handles[0], xx, yy);
7779
2/4
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 45680 times.
45680 if(replay_version_check(40))
7780 do_ffc_layer(screen_bmp, -1, screen_handles[0], xx, yy);
7781
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_layer(screen_bmp, 0, screen_handles[6], xx, yy);
7782
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 6, screen_handles[0], xx, yy);
7783
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 do_ffc_layer(screen_bmp, 7, screen_handles[0], xx, yy);
7784
7785
1/2
✓ Branch 0 taken 45680 times.
✗ Branch 1 not taken.
45680 stretch_blit(screen_bmp, mappic, 0, 0, 256, 176, x<<(8-mapres), (y*176)>>mapres, 256>>mapres, 176>>mapres);
7786
1/3
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 45680 times.
45680 }
7787 7784 }
7788
7789 973 viewport = prev_viewport;
7790 973 combotile_add_x = 0;
7791 973 combotile_add_y = 0;
7792
7793 973 destroy_bitmap(screen_bmp);
7794 973 clear_keybuf();
7795 973 pause_all_sfx();
7796
7797 // view it
7798 973 int32_t delay = 0;
7799
7800 973 do
7801 {
7802
2/2
✓ Branch 0 taken 178717 times.
✓ Branch 1 taken 29891 times.
208608 if (replay_version_check(0, 11))
7803 29891 load_control_state();
7804
7805 208608 int32_t step = int32_t(16.0/scales[sc]);
7806 208608 step = (step>>1) + (step&1);
7807 208608 bool r = cRbtn();
7808
7809
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(cLbtn())
7810 {
7811 step <<= 2;
7812 delay = 0;
7813 }
7814
7815
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 208608 times.
208608 if(r)
7816 {
7817 if(rUp())
7818 {
7819 py+=step;
7820 redraw=true;
7821 }
7822
7823 if(rDown())
7824 {
7825 py-=step;
7826 redraw=true;
7827 }
7828
7829 if(rLeft())
7830 {
7831 px+=step;
7832 redraw=true;
7833 }
7834
7835 if(rRight())
7836 {
7837 px-=step;
7838 redraw=true;
7839 }
7840 }
7841 else
7842 {
7843
2/2
✓ Branch 0 taken 193729 times.
✓ Branch 1 taken 14879 times.
208608 if(Up())
7844 {
7845 14879 py+=step;
7846 14879 redraw=true;
7847 14879 }
7848
7849
2/2
✓ Branch 0 taken 193574 times.
✓ Branch 1 taken 15034 times.
208608 if(Down())
7850 {
7851 15034 py-=step;
7852 15034 redraw=true;
7853 15034 }
7854
7855
2/2
✓ Branch 0 taken 182159 times.
✓ Branch 1 taken 26449 times.
208608 if(Left())
7856 {
7857 26449 px+=step;
7858 26449 redraw=true;
7859 26449 }
7860
7861
2/2
✓ Branch 0 taken 182774 times.
✓ Branch 1 taken 25834 times.
208608 if(Right())
7862 {
7863 25834 px-=step;
7864 25834 redraw=true;
7865 25834 }
7866 }
7867
7868
2/2
✓ Branch 0 taken 187444 times.
✓ Branch 1 taken 21164 times.
208608 if(delay)
7869 21164 --delay;
7870 else
7871 {
7872 187444 bool a = cAbtn();
7873 187444 bool b = cBbtn();
7874
7875
3/4
✓ Branch 0 taken 1721 times.
✓ Branch 1 taken 185723 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1721 times.
187444 if(a && !b)
7876 {
7877
1/2
✓ Branch 0 taken 1721 times.
✗ Branch 1 not taken.
1721 sc=zc_min(sc+1,16);
7878 1721 delay=8;
7879 1721 redraw=true;
7880 1721 }
7881
7882
3/4
✓ Branch 0 taken 927 times.
✓ Branch 1 taken 186517 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 927 times.
187444 if(b && !a)
7883 {
7884
2/2
✓ Branch 0 taken 926 times.
✓ Branch 1 taken 1 times.
927 sc=zc_max(sc-1,0);
7885 927 delay=8;
7886 927 redraw=true;
7887 927 }
7888 }
7889
7890
2/2
✓ Branch 0 taken 208597 times.
✓ Branch 1 taken 11 times.
208608 if(rPbtn())
7891 11 --view_map_show_mode;
7892
7893 208608 px = vbound(px,-4096,4096);
7894 208608 py = vbound(py,-1408,1408);
7895
7896 208608 double scale = scales[sc];
7897
7898
2/2
✓ Branch 0 taken 72838 times.
✓ Branch 1 taken 135770 times.
208608 if(!redraw)
7899 {
7900 135770 blit(scrollbuf_old,framebuf,256,0,0,0,256,232);
7901 135770 }
7902 else
7903 {
7904 72838 clear_to_color(framebuf,BLACK);
7905 145676 stretch_blit(mappic,framebuf,0,0,mappic->w,mappic->h,
7906 72838 int32_t(256+(int64_t(px)-mappic->w)*scale)/2,int32_t(224+(int64_t(py)-mappic->h)*scale)/2,
7907 72838 int32_t(mappic->w*scale),int32_t(mappic->h*scale));
7908
7909 72838 blit(framebuf,scrollbuf_old,0,0,256,0,256,232);
7910 72838 redraw=false;
7911 }
7912
7913 208608 int32_t x = int32_t(256+(px-((2048-int64_t(lx))*2))*scale)/2;
7914 208608 int32_t y = int32_t(224+(py-((704-int64_t(ly))*2))*scale)/2;
7915
7916
2/2
✓ Branch 0 taken 7466 times.
✓ Branch 1 taken 201142 times.
208608 if(view_map_show_mode&1)
7917 {
7918 201142 line(framebuf,x-7,y-7,x+7,y+7,(frame&3)+252);
7919 201142 line(framebuf,x+7,y-7,x-7,y+7,(frame&3)+252);
7920 201142 }
7921
7922
3/4
✓ Branch 0 taken 5600 times.
✓ Branch 1 taken 203008 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5600 times.
208608 if(view_map_show_mode&2 || r)
7923 203008 textprintf_ex(framebuf,font,224,216,WHITE,BLACK,"%1.2f",scale);
7924
7925
1/2
✓ Branch 0 taken 208608 times.
✗ Branch 1 not taken.
208608 if(r)
7926 {
7927 textprintf_ex(framebuf,font,0,208,WHITE,BLACK,"m: %d %d",px,py);
7928 textprintf_ex(framebuf,font,0,216,WHITE,BLACK,"x: %d %d",x,y);
7929 }
7930
7931 208608 advanceframe(false, false);
7932
2/2
✓ Branch 0 taken 29891 times.
✓ Branch 1 taken 178717 times.
208608 if (replay_version_check(11))
7933 178717 load_control_state();
7934
7935
2/2
✓ Branch 0 taken 207636 times.
✓ Branch 1 taken 972 times.
208608 if (getInput(btnS, INPUT_PRESS | INPUT_IGNORE_DISABLE))
7936 972 done = true;
7937
7938
2/2
✓ Branch 0 taken 207635 times.
✓ Branch 1 taken 973 times.
417216 }
7939
2/2
✓ Branch 0 taken 972 times.
✓ Branch 1 taken 207636 times.
208608 while(!done && !Quit);
7940
7941 973 ViewingMap = false;
7942 973 destroy_bitmap(mappic);
7943 973 resume_all_sfx();
7944 973 }
7945
7946 1075 int32_t onViewMap()
7947 {
7948
4/6
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 102 times.
✓ Branch 5 taken 973 times.
1075 if(Playing && cur_screen<128 && DMaps[cur_dmap].flags&dmfVIEWMAP)
7949 {
7950 973 clear_to_color(framebuf,BLACK);
7951 973 textout_centre_ex(framebuf,font,"Drawing map...",128,108,WHITE,BLACK);
7952 973 advanceframe(true);
7953 973 ViewMap();
7954 973 }
7955
7956 1075 return D_O_K;
7957 }
7958
7959 35757403 bool isGrassType(int32_t type)
7960 {
7961
2/2
✓ Branch 0 taken 35080991 times.
✓ Branch 1 taken 676412 times.
35757403 switch(type)
7962 {
7963 case cTALLGRASS:
7964 case cTALLGRASSNEXT:
7965 case cTALLGRASSTOUCHY:
7966 676412 return true;
7967 }
7968
7969 35080991 return false;
7970 35757403 }
7971
7972 20914 bool isFlowersType(int32_t type)
7973 {
7974
2/2
✓ Branch 0 taken 16574 times.
✓ Branch 1 taken 4340 times.
20914 switch(type)
7975 {
7976 case cFLOWERS:
7977 case cFLOWERSTOUCHY:
7978 4340 return true;
7979 }
7980
7981 16574 return false;
7982 20914 }
7983
7984 bool isGenericType(int32_t type)
7985 {
7986 switch(type)
7987 {
7988 case cTRIGGERGENERIC:
7989 return true;
7990 }
7991
7992 return false;
7993 }
7994
7995 26056 bool isBushType(int32_t type)
7996 {
7997
2/2
✓ Branch 0 taken 20914 times.
✓ Branch 1 taken 5142 times.
26056 switch(type)
7998 {
7999 case cBUSH:
8000 case cBUSHNEXT:
8001 case cBUSHTOUCHY:
8002 case cBUSHNEXTTOUCHY:
8003
8004 5142 return true;
8005 }
8006
8007 20914 return false;
8008 26056 }
8009
8010 bool isSlashType(int32_t type)
8011 {
8012 switch(type)
8013 {
8014 case cSLASH:
8015 case cSLASHITEM:
8016 case cSLASHTOUCHY:
8017 case cSLASHITEMTOUCHY:
8018 case cSLASHNEXT:
8019 case cSLASHNEXTITEM:
8020 case cSLASHNEXTTOUCHY:
8021 case cSLASHNEXTITEMTOUCHY:
8022 return true;
8023 }
8024
8025 return false;
8026 }
8027
8028 15695 bool isCuttableNextType(int32_t type)
8029 {
8030
2/2
✓ Branch 0 taken 9788 times.
✓ Branch 1 taken 5907 times.
15695 switch(type)
8031 {
8032 case cSLASHNEXT:
8033 case cSLASHNEXTITEM:
8034 case cTALLGRASSNEXT:
8035 case cBUSHNEXT:
8036 case cSLASHNEXTTOUCHY:
8037 case cSLASHNEXTITEMTOUCHY:
8038 case cBUSHNEXTTOUCHY:
8039 5907 return true;
8040 }
8041
8042 9788 return false;
8043 15695 }
8044
8045 17546 bool isTouchyType(int32_t type)
8046 {
8047
2/2
✓ Branch 0 taken 6050 times.
✓ Branch 1 taken 11496 times.
17546 switch(type)
8048 {
8049 case cSLASHTOUCHY:
8050 case cSLASHITEMTOUCHY:
8051 case cBUSHTOUCHY:
8052 case cFLOWERSTOUCHY:
8053 case cTALLGRASSTOUCHY:
8054 case cSLASHNEXTTOUCHY:
8055 case cSLASHNEXTITEMTOUCHY:
8056 case cBUSHNEXTTOUCHY:
8057 11496 return true;
8058 }
8059
8060 6050 return false;
8061 17546 }
8062
8063 29332374 bool isCuttableType(int32_t type)
8064 {
8065
2/2
✓ Branch 0 taken 28883109 times.
✓ Branch 1 taken 449265 times.
29332374 switch(type)
8066 {
8067 case cSLASH:
8068 case cSLASHITEM:
8069 case cBUSH:
8070 case cFLOWERS:
8071 case cTALLGRASS:
8072 case cTALLGRASSNEXT:
8073 case cSLASHNEXT:
8074 case cSLASHNEXTITEM:
8075 case cBUSHNEXT:
8076
8077 case cSLASHTOUCHY:
8078 case cSLASHITEMTOUCHY:
8079 case cBUSHTOUCHY:
8080 case cFLOWERSTOUCHY:
8081 case cTALLGRASSTOUCHY:
8082 case cSLASHNEXTTOUCHY:
8083 case cSLASHNEXTITEMTOUCHY:
8084 case cBUSHNEXTTOUCHY:
8085 449265 return true;
8086 }
8087
8088 28883109 return false;
8089 29332374 }
8090
8091 17322 bool isCuttableItemType(int32_t type)
8092 {
8093
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 16898 times.
17322 switch(type)
8094 {
8095 case cSLASHITEM:
8096 case cBUSH:
8097 case cFLOWERS:
8098 case cTALLGRASS:
8099 case cTALLGRASSNEXT:
8100 case cSLASHNEXTITEM:
8101 case cBUSHNEXT:
8102
8103 case cSLASHITEMTOUCHY:
8104 case cBUSHTOUCHY:
8105 case cFLOWERSTOUCHY:
8106 case cTALLGRASSTOUCHY:
8107 case cSLASHNEXTITEMTOUCHY:
8108 case cBUSHNEXTTOUCHY:
8109 16898 return true;
8110 }
8111
8112 424 return false;
8113 17322 }
8114
8115 66 bool is_push(mapscr* m, int32_t pos)
8116 {
8117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(m->sflag[pos]))
8118 return true;
8119 66 newcombo const& cmb = combobuf[m->data[pos]];
8120
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if(is_push_flag(cmb.flag))
8121 return true;
8122
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 52 times.
66 if(cmb.type == cPUSHBLOCK)
8123 14 return true;
8124
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 52 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
52 if(cmb.type == cSWITCHHOOK && (cmb.usrflags&cflag7))
8125 return true; //Counts as 'pushblock' flag
8126 52 return false;
8127 66 }
8128
8129 412 static std::map<int, screen_state_t> screen_states;
8130
8131 35854 std::map<int, screen_state_t>& get_screen_states()
8132 {
8133 35854 return screen_states;
8134 }
8135
8136 44182923 screen_state_t& get_screen_state(int screen)
8137 {
8138 44182923 return screen_states[screen];
8139 }
8140
8141 575 void clear_screen_states()
8142 {
8143 575 screen_states.clear();
8144 575 }
8145
8146 1439 void screen_item_set_state(int screen, ScreenItemState state)
8147 {
8148 1439 get_screen_state(screen).item_state = state;
8149 1439 }
8150
8151 37019 void mark_visited(int screen)
8152 {
8153
2/2
✓ Branch 0 taken 475 times.
✓ Branch 1 taken 36544 times.
37019 if (screen < 0x80)
8154 {
8155
2/2
✓ Branch 0 taken 24611 times.
✓ Branch 1 taken 11933 times.
36544 if(DMaps[cur_dmap].flags&dmfVIEWMAP)
8156 11933 game->maps[mapind(cur_map, screen)] |= mVISITED;
8157
8158 36544 markBmap(-1, screen);
8159 36544 }
8160 37019 }
8161